CATALOG -ACPMUG 1AVOLUME1 OCASSIGN SM? CASDSK SMCOPY SMECOPYX SMA !"#DIABLO SM$%&'INT.ASM MOD OF PRNT TO PERMIT CONDITIONAL ASSEMBLY FOR CON:/LST: AND FOR HARDWARE OR NONE 1.24 5K PRNT.ASM TRANSIENT TO PRINT FILES WITH PAGINATION AND PAGE NUMBERS 1.25 10K RELOC.ASM CP/M RELOCATION PROGRAM 1.26 7K RTE.ASM INTEL RE TO DISK TRANSFER 1.3 9K COPY.ASM COPY SYSTEM, DATA OR WHOLE DISKETTE FROM DRIVE A TO B. 1.4 8K COPY.COM AS ASM, USED TO COPY THIS DISK 1.5 9K COPYX.ASM AS COPY, USES INTERNAL SCRATCH INSTEAD OF AREA AT 40H 1.6 4K DIABLO.ASM ROMABLE HYTYPE/QU80 CAN DO IT ALL IN 4 INSTRUCTIONS!! 1.15 4K HYS13.ASM DIABLO DRIVER FOR 3P+S IN Z80 1.16 5K HYS15.ASM DIABLO DRIVER FOR 3P+S IN 8080 1.17 7K ICOPY.ASM COPY A FILE FROM ISIS DISKETTE ON B TO CP/M DISKETTE ON A. USE IDIR FIRST TO IDENTIFY DISSASM1SM@()*+,-./DISASSM2SM0123DISKTESTSMG456789:;<DSKCAS SM =>ED3 SM?EXAM SM7@ABCDEFFILES OMGGETVEC IBHO DESTROYS FILES ON DISKETTE AND ONLY RUNS IN 16K SYSTEMS 1.10 2K DSKCAS.ASM DISKETTE TO CASETTE TRANSFER 1.11 1K ED3.ASM PATCHES FOR 'R' BUG IN CP/M ED.COM 1.12 7K EXAM.ASM SECTOR VIEWER FOR VDM. SEE DISK1.DOC 1.13 1K FILES.COM GIVES CME DRIVER 1.7 8K DISASSM1.ASM CHRISTENSEN DISASSEMBLER AS PER DR. DOBB'S OF FEB 1977. SEE ALSO SEDIT.ASM BELOW 1.8 4K DISASSM2.ASM INTEL LIBRARY DISASSEMBLER 1.9 9K DISKTEST.ASM PROGRAM TO SEARCH FOR SOFT AND HARD SECTOR ERRORS IN DISK I/FILENAMES 1.18 6K IDIR.COM LISTS TO CONSOLE DIRECTORY OF ISIS DISKETTE IN B. 1.19 7K LIOS.ASM CP/M I/O SUBROUTINES. SEE PRINT FOR APPLICATION 1.20 10K LTG.ASM 1.21 6K MAZE.ASM INTEL MAZE PROGRAM 1.22 4K MEMTEST.ASM INTEL RAM TEST 1.23 7K PRVOLUME 1 VARIOUS CP/M UTILITY PROGRAMS NUMBER SIZE NAME COMMENTS 3K CATALOG.1 CONTENTS OF CP/M GROUP VOL 1 3K VOLUME1.DOC COMMENTS ON CERTAIN PROGRAMS ON VOLUME 1.1 8K ASSIGN.ASM IOBYTE ASIGN. USE WITH VBIOS31 1.2 2K CASDSK.ASM CASSETTEHYS13 SM IJKLHYS15 SM!MNOPQICOPY SM1RSTUVWXIDIR SM*YZ[\]^LIOS SM2_`abcdeLTG SMMfghijklmnoMAZE SM)pqrstuMEMTST SMvwxyONSOLE DISPLAY OF DIRECTORY RECORD NUMBERS ASSIGNED TO EACH FILE. OFFERS TO DELETE FAULTY DIRECTORY ENTRIES. 1.14 1K GETVEC.LIB ASM ROUTINE TO CREATE BIOS PRIMITIVE JUMP TABLE. BIG IMPROVEMENT ON ARG'S IN COPY. TOM KIRK SAYS A ZAL-TIME EXECUTIVE 1.27 4K SEDIT.ASM SYMBOL TABLE EDITOR OF DISASSM1 1.28 16K SPACE.ASM GAME 1.29 8K SPAT.ASM RE-WRITE OF EXAM TO ALLOW WRITING. SEE VOL 3 FORMAT.BAS AND README.FMI 1.30 3K TRAIN.ASM VDM GRAPHIC 1.31 4K TREAD.ASM TAPE READER TO DISE A +. MEMTST - IS A MEMORY TEST FROM THE INTEL USERS LIBRARY. IT HAS INTERNAL I/O ROUTINES AND MUST BE MODIFIED TO SUIT THE USERS SYSTEM. IT IS A VERY GOOD TEST OF MEMORY WHICH WE HAVE BEEN USING EXTENSIVELY IN THE LONG ISLAND CLUB. THE PROG8701 JZ EXIT ;QUIT 0128 CD0301 CALL INIT ; 0122 119201 LXI D,CMDMSG ;DEFAULT TO COMMAND ERROR MESSAGE 0125 CB 0E0F MVI C,15 ;OPEN FILE COMMAND 012D 115C00 LXI D,FCB ;POINT TO FILE CONTROL BLOCK 0130INIT SERIAL PORT 01N IF DESIRED. THE VDM DRIVER HAS SPEED CONTROL USING THE FRONT PANEL SWITCHES. IDIR -READS DIRECTORY OF ISIS (INTEL FDOS) DISKETTE IN DRIVE B ICOPY -READS FILE FROM ISIS DISKETTE IN DRIVE B, AFTER FINDING NAME FROM USING IDIR, AND COPIES AS CON UTILITY FOR A SYSTEM EQUIPPED WITH A VDM. ONCE RUNNING EXAM WILL ALLOW VISUAL EXAMINATION OF ANY SECTOR ON THE DISK (DRIVE 0 ONLY IN THIS VERSION). THE CURRENT VERSION WILL ONLY OPERATE IN A 16K SYSTEM BUT THAT IS EASILY FIXED. THE COMMANDS K TRANSFER 1.32 17K VBIOS31.ASM BIOS FOR 32K OF MEMORY WITH VDM 1.33 3K VBOOT31 COLD BOOT FOR VBIOS31 1.34 1K XSTAT.COM SIMILAR TO STAT. REPORTS # OF FILES AND NULL FILES. KNOWN BUG IS THAT IS REPORTS NULL EXTENTS TO NON-NULL FILES. DON'TA TO BE PRINTED. ASSIGN - IS THE DEVICE ASSIGNMENT UTILITY TO BE USED WITH THE VBIOS SUPPLIED. IT SHOULD BE ASSEMBLED TO OBTAIN THE DOCUMENTATION. MAZE - IS A MAZE PROGRAM FROM THE INTEL USERS LIBRARY. IT SHOULD RUN ON ANY SYSTEM. TRAIN -RAM WILL DISPLAY MEMTST 1.0 AT WHICH POINT THE USER SHOULD ENTER STARTING AND ENDING HEX ADDRESSES SEPERATED BY A COMMA. THE PROGRAM WILL THEN TYPE ADDR: REF: ACT: AND BEGIN TESTING. ANY ERRORS WILL CAUSE AN ADDRESS ,REFERENCE DATA, AND ACTUAL DAPRNT - IS A PRINT UTILITY SOMETHING LIKE TYPE BUT WITH PAGINATION AND HEADINGS. IT SHOULD RUN ON ANY CONFIGURATION OF CP/M WITH AN I/O DEVICE THAT RECOGNIZES A FORM FEED CHARACTER (HEX 0C) AS A TOP-OF PAGE COMMAND. THE SYNTAX FOR USING PRNT IS: P/M FILE TO A COMMAND: "ICOPY FILNAME.TYP" LIOS -SET OF SUBROUTINES TO PERFORM CP/M LOGICAL FUNCTIONS FOR INCORPORATION IN NEW PROGRAMS  TO EXAM ARE: + = READ NEXT SECTOR - = READ PREVIOUS SECTOR I = STEP HEAD IN (TOWARD TRACK 76) AND READ O = STEP HEAD OUT (TOWARD TRACK 0) AND READ DUE TO A MINOR BUG WHICH I HAVEN'T HAD THE TIME TO FIX, THE FIRST COMMAND TO EXAM SHOULD BT DELETE A FILE BASED ON THIS!!!!! LAR TO STAT. REPORTS # OF FILES AND NULL FILES. KNOWN BUG IS THAT IS REPORTS NULL EXTENTS TO NON-NULL FILES. DON' IS THE VDM TRAIN PROGRAM FROM THE PROCESSOR TECHNOLOGY NEWSLETTER. JUST TYPE TRAIN. VBIOS31 AND BOOT31 ARE THE TWO PIECES OF A DEVICE-SELECTABLE CBIOS WITH A BUILT-IN VDM DRIVER. THESE TWO PIECES SHOULD BE INCORPORATED IN A SECOND LEVEL SYSGE WORK WITH A TELETYPE HAVING AN AUTOMATIC READER. THE TAPES TO BE READ MUST CONTAIN CR, LF SEQUENCES PERIODICALLY. THE TAPE MAY BE ENDED WITH A CONTROL Z. SYNTAX FOR USING THIS PROGRAM IS: TREAD FILENAME.EXT EXAM - IS A DISK SECTOR EXAMINATI PRNT FILENAME.EXT PRNT ALSO MAY BE USEFUL TO THOSE WHO NEED AN EXAMPLE OF CP/M DISK I/O ACCESS. PRINT - IS A PATCHED VERSION BY ARG TO COPE WITH HARDWARE THAT DOES NOT RECOGNISE 0CH TREAD - IS A PAPER-TAPE TO DISK UTILITY WHICH WILL ONLY;*****************************************************; ; ; ASSIGNMENT UTILITY ; ; VERSION 1.0 05/77 ; ;*****************************************************; IOBYTE EQU 3 ;IO ASSIGNMENTS BYTE - WHAT THIS PROGRAM SETS STRLOC EQU 80H ;WHERE CLDTL ;IF EITHER WRONG, TRY ;FOUND IT, FETCH VALUES FROM TABLE INX H! MOV A,M! STA MASK ;MASK FOR CHANGING IOBYTE INX H! MOV A,M! INX H! MOV H,M! MOV L,A ;LOCATION PHYS DEV TAB FOR THIS LOG DEV POP D! POP D ;CLEAR STACK ; XTHL ;PUT PHYS DE 'PRN ',10000000B ;SYNONYM FOR LPT DB 'LST3 ',11000000B ;FOR USER-ADDED DEVICE DB 0FFH ; ; ************* MAIN PROGRAM ******************** ASSIGN: LXI H,0! DAD SP! SHLD CALLERSP ;SAVE CALLER'S STACK LXI SP,STACK ;SET UP OURS ; ; VALUES. ;TO CHANGE DEVICE NAMES OR IOBYTE VALUES, THE USER ;NEED ONLY CHANGE THESE TABLES. ;LOGICAL DEVICE TABLE: NAMES ACCEPTED BEFORE '=' ; FORMAT: ASCII NAME (OMIT COLON), SPACE, MASK FOR ; ZEROING IOBYTE FIELD RELATED TO NAME (1 BYTE), ; USH D! PUSH B INX H! INX H! INX H! INX H ;PASS DATA FOR PREVIOUS ENTRY ;LOOP OVER CHARS OF ENTRY SLDEL: MOV A,M ;CHAR OF ENTRY CPI 0FFH! JZ LDEVNF ;TEST FOR END OF TABLE CPI ' '! JZ ENDLENTRY ;TEST FOR END THIS ENTRY KEY LDAX D! CMP M! JZ SLDTLE DB 0FFH RDRFDEV: ;SYSTEM READER DEVICE DB 'TTY ',0 DB 'RDR ',100B ;HIGH SPEED READER (UNIMPLEMENTED) DB 'RDR2 ',1000B ;UNIMPLEMENTED - FOR USER-ADDED DEVICE DB 'RDR3 ',1100B ; DITTO DB 0FFH PUNFDEV: ;SYSTEM PUNCH DEVICE DB 'TTY ',0 CP LEAVE ARGUMENT STRING ENTRY EQU 5 ;SYSTEM CALL ENTRY POINT REBOOT EQU 0 ;WHERE TO JMP TO REBOOT SYSTEM TBASE EQU 100H ;WHERE PROGRAM BEGINS ;EQUATES FOR ASCII CONTROL CHARACTERS CTRLC EQU 3 TAB EQU 9 LF EQU 0AH CR EQU 0DH RUBOUT EQU 7FH RE POINTER TO BEGINNING ;IF NULL ARG, GO ASSIGN FROM SWITCHES CALL PASS$SP! CPI CR! JZ ASSWITCHES ;PARSE LOGICAL DEVICE NAME DCX H! CALL SCANDVN ;SCAN NAME, SET C=LEN,DE=START ;ALLOW A SEPERATING CHARACTER IN ADDITION TO SPACES CPI '='! JZ ANALYZE AND EXECUTE GIVEN COMMAND ; LXI H,STRLOC ;STRING POINTER STAYS IN HL ;INPUT IS COUNT FOLLOWED BY CHARACTERS. PUT CR AT END. PUSH H MOV E,M ;COUNT MVI D,0! DAD D! INX H ;POINT CHR POSN AFTER END MVI M,CR ;PUT CR THERE POP H ;RESTO ADDRESS OF PHYSICAL DEVICE TABLE FOR THIS LOG DEVICE. ; LDEVTAB: ;A LONG AND A SHORT NAME FOR EACH -- DB 'CON ',11111100B DW CONFDEV DB 'CONSOLE ',11111100B DW CONFDEV DB 'RDR ',11110011B DW RDRFDEV DB 'READER ',11110011B DW RDRF2 ;COMPARE TO CHAR OF ARGUMENT INR B ;CHAR DOESN'T MATCH, FLAG AND CONTINUE SLDTL2: INX H! INX D! DCR C! JMP SLDEL ;KEEP TESTING ENTRY ;END OF CURRENT ENTRY ENDLENTRY: MOV A,C ;TEST FOR LENGTH CORRECT ORA B ;TEST FOR ALL CHARS MATCHING JNZ S DB 'PUN ',10000B ;HI SPEED PUNCH (UNIMPLEMENTED) DB 'PUN2 ',100000B ;UNIMPLEMENTED - FOR USER DEVICE DB 'PUN3 ',110000B ;DITTO DB 0FFH LSTFDEV: ;SYSTEM LIST DEVICE DB 'TTY ',0 DB 'CRT ',01000000B DB 'LPT ',10000000B ;IMSAI LINE PRINTER DB ORG TBASE JMP ASSIGN ;NORMAL ENTRY JMP DTEST ;DDT DEBUGGING ENTRY ; *********** DEVICE TABLES ************** ;THESE TABLES GIVE THE LOGICAL DEVICE NAMES ;AND THE PHYSICAL DEVICE NAMES ASSOCIATED WITH EACH, AND THE ;CORRESPONDING IOBYTEPASSEP CPI '_'! JZ PASSEP CPI ','! JZ PASSEP DCX H ;ELSE CURRENT CHAR STARTS PHYS DEV NAME PASSEP: PUSH H ;SAVE STRING POINTER ;SEARCH LOGICAL DEVICE TABLE LXI H,LDEVTAB-4 PUSH D MVI B,0! PUSH B ;LOOP OVER ENTRIES SLDTL: POP B! POP D! PFOR EACH LOGICAL DEVICE. ; FORMAT: NAME, SPACE, PROPERLY POSITIONED IOBYTE VALUE CONFDEV: ;FOR CONSOLE - INPUT AND OUTPUT DB 'TTY ',0 DB 'CRT ',1 DB 'BATCH ',2 ;BATCH MODE: INPUT LOGICAL READER, OUTPUT LIST. DB 'CON3 ',3 ;FOR A USER-ADDED DEVICDEV DB 'PUN ',11001111B DW PUNFDEV DB 'PUNCH ',11001111B DW PUNFDEV DB 'LST ',00111111B DW LSTFDEV DB 'LIST ',00111111B DW LSTFDEV DB 0FFH ;THIS MARKS END OF TABLE ;PHYSICAL DEVICE NAME TABLES: NAMES ACCEPTABLE AFTER '='. ;ONE V TAB PTR, GET STRING POINTER ; ; PARSE PHYS DEV NAME CALL SCANDVN ;CHECK TERMINATING CHAR CPI CR! JNZ SYNER ; POP H ;DISCARD STRING PTR, GET PHYS DEV TBL LOC ;SEARCH PHYS DEV TABLE (HL) ;PARALLEL TO LOG DEV TABLE SEARCH ABOVE DCX H! TACK: END DTEST ****** ; CALLERSP: DS 2 ;CALLER'S STACK POINTER MASK: DS 1 ;BIT MASK FOR IOBYTE FIELD TO CHANGE DS 40 STACK: DS 10 DS C, NEXT CHAR A SCANDVN: SCD1: INX H! MOV A,M! CPI ' '! JZ SCD1 ;PASS PRECEDING SPACES PUSH H ;SAVE BEGINNING MVI C,0 ;CHAR COUNTER (RUNS 1 HI) DCX H ;SCAN NAME INSELF SCDL: INR C! INX H! MOV A,M ;NEXT CHARACTER ;END SCAN ON : = CR _ OR SPA CCP DOES & MAKE IT LOOK THE SAME LXI H,STRLOC-1 ;BUFFER LOC MVI M,72 ;LENGTH MVI C,10 ;BUFFERED CONSOLE INPUT FUNCTION MOV D,H! MOV E,L CALL ENTRY MVI A,LF! CALL CONO ;ECHO LF AFTER CR ;NOW USE ASSIGN PROGRAM CALL ASSIGN RST 7 ;THEN ;OUTPUT CRLF TO CONSOLE & CLOBBER DE CRLF: LXI D,CRLFM ;OUTPUT MESSAGE (DE) TO CONSOLE TMSG: PUSH PSW! PUSH B! PUSH D! PUSH H MVI C,9 JMP CALLEN CRLFM: DB CR,LF,'$' ;OUTPUT CHARACTER (A) TO CONSOLE CONO: PUSH PSW! PUSH B! PUSH D! PUSGNIZED LOGICAL DEVICE$' ;PHYSICAL DEVICE NOT FOUND IN TABLE FDEVNF: CALL TDEVN CALL INLMSGEXIT! DB ' NOT LEGAL PHYSICAL DEVICE FOR GIVEN LOGICAL DEVICE$' ;GENERAL SYNTAX ERROR: TYPE LINE AND ? SYNER: LXI D,STRLOC LDAX D! MOV C,A ;CHAR COUNT TODCX H ;ADJUST TABLE PTR FOR INX'S BELOW PUSH D MVI B,0! PUSH B SFDTL: POP B! POP D! PUSH D! PUSH B INX H! INX H SFDEL: MOV A,M CPI 0FFH! JZ FDEVNF CPI ' '! JZ ENDFENTRY LDAX D! CMP M! JZ SFDTL2 INR B SFDTL2: INX H! INX D! DCR C! JMP SFDEL ' '! RNZ! INX H! MOV A,M! JMP SCD6 ;PASS FOLLOWING SPACES ;TYPE DEVICE NAME AFTER SEARCH ERROR ;DE POINTS BEGINNING, C GIVES LENGTH TDEVN: XCHG TDEVN1: MOV A,M! CALL CONO! INX H! DCR C! JNZ TDEVN1 MVI A,':'! JMP CONO ;TYPE MESSAGE FOLLOWINGCE CPI ' '! JZ SCD4! CPI ':'! JZ SCD4! CPI CR! JZ SCD4 CPI '='! JZ SCD4! CPI '_'! JNZ SCDL ; SCD4: DCR C! JZ SYNER ;ERROR IF NO CHARACTERS IN NAME ;PASS UP FOLLOWING COLON CPI ':'! JNZ $+4! INX H! MOV A,M POP D ;POINTER TO BEGINNING SCD6: CPIRETURN TO DDT ; ; ***** NORMAL FLOW OF PROGRAM ENDED ABOVE, EXECPTION CASES FOLLOW ****** ; ; ASSIGN FROM SWITCHES ; ASSWITCHES: ;GET USER TO CONFIRM, SINCE IF THERE'S A WRONG ; VALUE IN SWITHCES, HIS CONSOLE SOULD DISSAPPEAR LXI D,ASWMSG!H H MOV E,A! MVI C,2 CALLEN: CALL ENTRY RETREGS: POP H! POP D! POP B! POP PSW! RET ; ; ************ STORAGE ************** ; CALLERSP: DS 2 ;CALLER'S STACK POINTER MASK: DS 1 ;BIT MASK FOR IOBYTE FIELD TO CHANGE DS 40 STACK: DS 10 DS C INX D! CALL TDEVN ;TYPE LINE QUES: CALL INLMSGEXIT! DB ' ?$' ; ; ; ************* SUBROUTINES ******************* ; ;PASS SPACES, GET CHARACTER PASS$SP: INX H! MOV A,M! CPI ' '! JZ PASS$SP! RET ;SCAN DEVICE NAME (HL), RET BEG DE, COUNT ENDFENTRY: MOV A,C ORA B JNZ SFDTL ;FOUND IT ;UPDATE IOBYTE INX H LDA IOBYTE! MOV B,A LDA MASK! ANA B ORA M! STA IOBYTE ;DONE, EXIT TO CCP JMP GDEXIT ; ; DDT CHECKOUT MAIN PROGRAM ; DTEST: LXI SP,DSTACK ;INPUT STRING TO SAME PLACE CALL AND EXIT INLMSGEXIT: POP D ;MESSAGE IS AT CALLING LOC ;TYPE MESSAGE (DE) AND ABORT MSGABORT: CALL TMSG ;ERROR RETURN TO CCP EREXIT: MVI A,1! JMP $+4 ;GOOD RETURN TO CCP GDEXIT: XRA A CALL CRLF LHLD CALLERSP! SPHL! RET ; IN 0FFH ;PUTS SWITCHES VALUE IN A STA IOBYTE ;STORE IT JMP GDEXIT ASWMSG: DB 'SET SWITCHES TO DESIRED IOBYTE VALUE, TYPE RETURN$' ;LOGICAL DEVICE NOT FOUND IN TABLE LDEVNF: CALL TDEVN ;TYPE DEVICE NAME AND COLON CALL INLMSGEXIT! DB ' UNRECO CALL TMSG ;"SET SWITCHES, TYPE RETURN" MVI C,1! CALL ENTRY ;INPUT CHARACTER FROM CONSOLE CPI RUBOUT! JZ GDEXIT ;IGNORE IF RUBOUT CPI CTRLC! JZ REBOOT ;RELOAD SYSTEM ON ^C CPI CR! JNZ QUES ;"?" ON CHAR OTHER THAN CR ;NOW INPUT AND STORE SWITCHES ; CASDSK - TRANSFER CASSETTE TO DISK ; TARBELL ELECTRONICS ; ORG 100H FDOS: EQU 5 ;DISK SYSTEM ENTRY POINT. TFCB: EQU 5CH ;DEFAULT FILE CONTROL BLOCK. TBUFF: EQU 80H ;DEFAULT BUFFER LOCATION. MVI C,22 ;CREATE FILE. LXI D,TFCB CALL FDOS DB '+PERMANENT DESTINATION DISK ERROR EXIT $' SIGNON: DB 13,10,'+SOURCE ON A' DB 13,10,'+OBJECT ON B' SINOFF: DB 13,10,'+TYPE $' CRLF: DB 13,10,'$' ; ; PRTHEX: PUSH PSW ;SAVE FOR LSN RAR ;SHIFT MSNIBLE TO LSN RAR RAR RAR CALL PRTNBLKS 0 AND 1 WITH THE COMMAND "COPY SYSTEM" ; 2 TO 76 WITH THE COMMAND "COPY DATA" AND ; 0 TO 76 WITH THE COMMAND "COPY ALL" ;THE PROGRAM WILL OPERATE WITH A STANDARD CPM SYSTEM OF ANY ;SIZE. BECAUSE OF THE POTEL FDOS JMP CLOSE ;CLOSE FILE AND LEAVE. QERR: DB 'TAPE ERROR$' ; CTRD - READ A RECORD FROM CASSETTE. ; CTRD: CALL CASW ;DELAY TO ALLOW LAST CALL CASW ;BYTE TO PASS THROUGH. MVI E,0 ;SET CHECKSUM=0. MVI A,10H ;SET BIT 4=1. OUT CASC ;RESE****************************** HOME: JMP DUMYADR SELDSK: JMP DUMYADR SETTRK: JMP DUMYADR SETSEC: JMP DUMYADR SETDMA: JMP DUMYADR READ: JMP DUMYADR WRITE: JMP DUMYADR ;************************************************************ ;EQUATES EXITCPM E20H ;LOOK AT BIT 5. JNZ CLOP ;WAIT UNTIL READY. POP PSW ;RECOVER DATA. OUT CASD ;WRITE A BYTE. RET ;RETURN FROM CASW. CASC: EQU 6EH ;STATUS PORT. CASD: EQU 6FH ;DATA PORT. END  MVI C,15 ;OPEN FILE. LXI D,TFCB CALL FDOS MLOOP: LXI H,TBUFF ;GET ADDRESS OF BUFFER. CALL CTRD ;READ RECORD FROM CASSETTE. JNZ ERROR ;ERROR IF NOT ZERO. MOV A,B ;GET RECORD LENGTH AND ORA A ;CHECK FOR LENGTH 0 (EOF). JZ CLOSE ;IF TION OF THE SCRATCH AREA, SO THAT IT CAN BE ;USED WITH THE DIGITAL SYSTEMS FDC3 CONTROLLER. ; ;ALSO THE PROGRAM PAUSES AFTER LOADING SO THAT THE DISKS ;CAN BE CHANGED. ;TOM KIRK (609) 921-0321. ;*******************************************************NTIAL POWER OF THIS PROGRAM ;THE INITIATING COMMAND IS TESTED FOR PRECISE SYNTAX. ;TONY GOLD (212) 722-3416. ;------------------------------------------------------------ ;7/23/77 ;THIS PROGRAM HAS BEEN REWRITTEN TO REMOVE THE DEPENDENCE ;ON THE LOCAT RECEIVER. CALL CASR ;READ TYPE BYTE. CALL CASR ;READ LENGTH BYTE. MOV B,A ;PUT LENGTH BYTE IN B. RZ ;RETURN IF LENGTH 0. MOV C,A ;PUT LENGTH IN C TOO. CRLOP: CALL CASR ;READ DATA BYTE. MOV M,A ;PUT INTO MEMORY. INX H ;INCREMENT POINTQU 0 LASTSEC EQU 26 BDOS EQU 5 ;************************************************************ ; MESGA: DB 0DH,0AH,'+COMPARE ERROR ON TRACK $' MESGB: DB '(HEX) SECTOR $' MESGC: DB 'PERMANENT $' MESGD: DB '+PERMANENT SOURCE DISK ERROR EXIT $' MESGE: ;************************************************************ ;THIS PROGRAM IS A MODIFICATION OF "COPYATOB.COM" WHICH ;HAS BEEN RE-WRITTEN TO OPERATE BOTH THROUGH CPM BDOS CALLS ;AND DIRECTLY WITH BIOS PRIMITIVES. THE PROGRAM CAN BE ;USED TO COPY TRACEOF, CLOSE FILE. MVI C,21 ;WRITE A RECORD ONTO DISK. LXI D,TFCB CALL FDOS JMP MLOOP ;GET THE NEXT ONE. CLOSE: MVI C,16 ;CLOSE FILE. LXI D,TFCB CALL FDOS JMP 0 ;DO A WARM-START. ERROR: LXI D,QERR ;PRINT "TAPE ERROR". MVI C,9 CAL***** ;REVISED TO KEEP COPYX FEATURES BUT RETURN SCRATCH AREA ;TO 40H. ;A.R.G 10/14/77 (VERSION 1.3) ;************************************************************ ORG 100H ; ; JMP VECTOR DB 'COPY VERSION 1.3' ;******************************R ;WAIT TILL READY. IN CASD ;READ DATA. PUSH PSW ;SAVE REG A. ADD E ;ADD TO CHECKSUM. MOV E,A POP PSW ;RESTORE A. ORA A ;SET FLAGS. RET ;RETURN FROM CASR. ; CASW: PUSH PSW ;SAVE DATA ON STACK. CLOP: IN CASC ;READ STATUS. ANI ER. DCR C ;DECREMENT COUNTER. JNZ CRLOP ;READ ANOTHER BYTE. MOV C,E ;PUT CHECKSUM IN C. CALL CASR ;READ CHECKSUM. SUB C ;SUBTRACT FROM A. RET ;RETURN FROM CRLOP. ; CASR: IN CASC ;READ CASS. STATUS. ANI 10H ;CHECK BIT 4. JNZ CAS ;PRINT IT POP PSW ;NOW FOR LSN PRTNBL: ANI 0FH ADI 30H ;SHIFT TO ASCII VALUE CPI 3AH ;OVER 9? JC SML ADI 7 ;SHIFT TO ALPHA SML: MOV E,A ;FOR BDOS CALL MVI C,2 ;WRITE CONSOLE FUNCTION CALL BDOS RET ; ; COPY: MVI C,0 CALL SELDSK ;SEB 'ATA$' ;DATA MESSAGE ALLMSG: DB 'LL$' ;ALL MESSAGE TRKSRT: DW 0 ;STORAGE FOR FIRST AND LAST+1 TRACK NUMBERS CMDER1: DB '+COMMAND "COPY$' CMDER2: DB '" HAS SYNTAX ERROR',0DH,0AH,'$' CMDINF: DB '+THIS PROGRAM IS INITIATED WITH THE COMMAND',0DH,0AH ; DISKNO = LAST SELECTED DISK NUMBER ; (NOTE THAT ALL ARE BYTE VALUES EXCEPT FOR DMAAD) ; SCRAT EQU 40H TRACK EQU SCRAT ;CURRENT TRACK ON DRIVE 0 TRAK1 EQU TRACK+1 ;CURRENT TRACK ON DRIVE 1 SECTOR EQU SCRAT+2 ;CURRENTLY SELECTED SECTOR DMAADDA TRK INR A STA TRK LXI H,TRKSRT+1 ;POINT TO LAST TRACK+1 STORAGE CMP M ;ARE WE DONE? JNZ RDLOOP ;LOOP IF NOT RET ; ; COMPT: LXI H,BUF1 CALL RT2 ;REREAD INTO BUF1 LXI H,BUF0 LXI D,BUF1 LXI B,128*LASTSEC CMPLP: LDAX D CMP M JNZ ********************************* RUNTYP: JMP BUFMSR ;THIS ROUTINE SETS UP THE PARAMETERS FOR THE COPY ROUTINE. ;COPY CAN BE USED TO TRANSFER: SYS TRACKS 0- 1 ; DAT TRACKS 2-76 ; ALL TRACKS 0-76 ;THE ROUTINE SEARCHES THE DEFAULT BUFFER AT 80HOP B MVI A,LASTSEC CMP C RZ INR C JMP RT3 ; ; WRITET: LXI H,BUF0 ;TRACK # IN C WT2: SHLD DMAAD CALL SETTRK MVI C,1 WT3: PUSH B CALL SETSEC CALL WRITE RAR ;WAS A BIT 0 SET BY DISK ERROR? CC FAILW LHLD DMAAD LXI D,128 DAD D LECT DISK A LDA TRKSRT ;FIRST TRACK TO MOVE STA TRK ;MAKE CURRENT MOV C,A CALL SETTRK ;AND SELECT IT ON DISK A MVI C,1 CALL SELDSK ;ALSO B LDA TRKSRT ;FIRST TRACK TO MOVE MOV C,A CALL SETTRK ;AND SELECT IT ON DISK B RDLOOP: MVI C,0 XRA UP JUMP VECTORS FOR ACCESS TO BIOS PRIMITIVES BASE EQU 0 ;FIND WBOOT JMP ADDRESS AT RST0 DUMYADR EQU 0 ;WHO CARES? ; LHLD BASE+1 ;GET WBOOT ADDRESS SPHL ;SAVE IT IN SP FOR DAD ; LXI H,15H DAD SP SHLD HOME+1 ; LXI H,18H DAD SP SHLD S EQU SCRAT+3 ;CURRENT DMA ADDRESS DISKNO EQU SCRAT+5 ;CURRENT DISK NUMBER DUMMY EQU DISKNO+1 ;MUST BE 0 FOR DOUBLE ADD ; ; ; ; BUF0: DS 128*LASTSEC BUF1: DS 128*LASTSEC ;************************************************************ VECTOR: ;SETCERR INX H INX D DCR C JNZ CMPLP DCR B ;ARE WE AT END OF BUFFER? JNZ CMPLP RET CERR: PUSH B LXI D,MESGA MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL CALL BDOS LDA TRK CALL PRTHEX LXI D,MESGB MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL FOR THE ;RUN PARAMETER TO BE USED ;************************************************************ ;ROUTINE EQUATES TBUFF EQU 80H ;************************************************************ ;DATA TABLES SYSMSG: DB 'YSTEM$' ;SYSTEM MESSAGE DATMSG: D SHLD DMAAD POP B MVI A,LASTSEC CMP C RZ INR C JMP WT3 CMPERR: DB 0 ;NUMBER OF COMPARE ERRORS TRK: DB 0 STK: DS 32 STKTOP: DB 0 ; TRACK = LAST SELECTED TRACK ; SECTOR = LAST SELECTED SECTOR ; DMAAD = LAST SELECTED DMA ADDRESS A STA CMPERR CALL SELDSK LDA TRK ;GET TRACK MOV C,A CALL READT ;READ ENTIRE TRACK RETRYW: MVI C,1 CALL SELDSK LDA TRK MOV C,A CALL WRITET ;WRITE TRACK LDA TRK MOV C,A CALL COMPT ;REREAD AND COMPARE JNZ RETRYW ;RETRY IF ERR LELDSK+1 ; LXI H,1BH DAD SP SHLD SETTRK+1 ; LXI H,1EH DAD SP SHLD SETSEC+1 ; LXI H,21H DAD SP SHLD SETDMA+1 ; LXI H,24H DAD SP SHLD READ+1 ; LXI H,27H DAD SP SHLD WRITE+1 ; LXI SP,STKTOP ; ;***************************LXI D,MESGC CALL BDOS XRA A RET ; ; READT: LXI H,BUF0 ;TRACK # IN C RT2: SHLD DMAAD CALL SETTRK MVI C,1 RT3: PUSH B CALL SETSEC CALL READ RAR ;WAS A BIT 0 SET BY DISK ERROR? CC FAILR LHLD DMAAD LXI D,128 DAD D SHLD DMAAD P CALL BDOS POP H ;PUSHED FROM B DAD H ;COMPUTE SECTOR IN ERROR LXI D,0FF00H DAD D MVI A,27 SUB H CALL PRTHEX ;PRINT SECTOR LDA CMPERR INR A STA CMPERR ;INCREMENT ERROR COUNT CPI 10 RNZ MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL DB '+"COPY SYSTEM", "COPY DATA" OR "COPY ALL"$' DONMSG: DB '+FUNCTION COMPLETE$' ;************************************************************ ;FIRST WE MEASURE THE INPUT BUFFER MESSAGE ;AND DELIMIT IT WITH A $ PER BDOS CALL 9 BUFMSR: LXI H,TBUFF TION OF THE SCRATCH AREA, SO THAT IT CAN BE ;USED WITH THE DIGITAL SYSTEMS FDC3 CONTROLLER. ; ;ALSO THE PROGRAM PAUSES AFTER LOADING SO THAT THE DISKS ;CAN BE CHANGED. ;TOM KIRK (609) 921-0321. ;******************************************************************* FAILR: LXI D,MESGD JMP DIE FAILW: LXI D,MESGE MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL DIE: CALL BDOS ;************************************************************ EXIT: LXI D,SINOFF MVI C,9 CALL BDOS MVI C,1 CALL BDOS CPI ********************************* SYSSET: LXI D,SYSMSG MVI C,6 CALL MSGTST MVI L,0 ;FIRST TRACK TO TRANSFER MVI H,2 ;LAST TRACK PLUS ONE JMP PUTPAR ;************************************************************ DATSET: LXI D,DATMSG MVI KS 0 AND 1 WITH THE COMMAND "COPY SYSTEM" ; 2 TO 76 WITH THE COMMAND "COPY DATA" AND ; 0 TO 76 WITH THE COMMAND "COPY ALL" ;THE PROGRAM WILL OPERATE WITH A STANDARD CPM SYSTEM OF ANY ;SIZE. BECAUSE OF THE POTE************ MSGTST: LXI H,TBUFF+3 LDAX D CMP M ;SAME AS MESSAGE? JNZ BADMSG INX H INX D DCR C ;REDUCE CHARACTER COUNTER RZ ;FINISHED OK JMP MSGTST+3 ;CHECK OUT NEXT CHARACTER ;*********************************************************XRA A ;CLEAR ACC. ADD M ;GET MESSAGE SIZE JZ NOMSG ;NONE FOUND INX H ;ADD FOR ADDR. PAST MESSAGE MVI B,0 ;EMPTY FOR DAD MOV C,A DAD B ;ADD CHARACTER COUNT TO HL MVI M,'$' ;END BUFFER CHARACTER ;****************************************13 JNZ EXIT JMP EXITCPM END ********************************************************* EXIT: LXI D,SINOFF MVI C,9 CALL BDOS MVI C,1 CALL BDOS CPI C,4 CALL MSGTST MVI L,2 ;FIRST TRACK TO TRANSFER MVI H,77 ;LAST TRACK PLUS ONE JMP PUTPAR ;************************************************************ ALLSET: LXI D,ALLMSG MVI C,3 CALL MSGTST MVI L,0 ;FIRST TRACK TO TRANSFER MVI H,7NTIAL POWER OF THIS PROGRAM ;THE INITIATING COMMAND IS TESTED FOR PRECISE SYNTAX. ;TONY GOLD (212) 722-3416. ;------------------------------------------------------------ ;7/23/77 ;THIS PROGRAM HAS BEEN REWRITTEN TO REMOVE THE DEPENDENCE ;ON THE LOCA*** BADMSG: LXI D,CMDER1 MVI C,9 CALL BDOS LXI D,TBUFF+1 ;PRINT ERRONEOUS COMMAND MVI C,9 CALL BDOS LXI D,CMDER2 MVI C,9 CALL BDOS NOMSG: LXI D,CMDINF MVI C,9 CALL BDOS JMP EXITCPM ;******************************************************************** ;NEXT IS A TEST FOR WHICH MESSAGE IS PRESENT LDA TBUFF+2 ;FIRST CHARACTER ADDRESS CPI 'S' JZ SYSSET CPI 'D' JZ DATSET CPI 'A' JZ ALLSET JMP BADMSG ;FIRST CHARACTER NOT ONE OF 3 PERMITTED ;***************************;************************************************************ ;THIS PROGRAM IS A MODIFICATION OF "COPYATOB.COM" WHICH ;HAS BEEN RE-WRITTEN TO OPERATE BOTH THROUGH CPM BDOS CALLS ;AND DIRECTLY WITH BIOS PRIMITIVES. THE PROGRAM CAN BE ;USED TO COPY TRACXI D,CRLF MVI C,9 CALL BDOS ;************************************************************ CALL COPY ;MAIN ROUTINE LXI D,DONMSG ;SAY WE'RE DONE MVI C,9 CALL BDOS JMP EXIT ;DONE. NOW GET OUT ;************************************************7 ;LAST TRACK PLUS ONE PUTPAR: SHLD TRKSRT ;PUT PARAMETERS IN TRKSRT AND TRKSRT+1 ;************************************************************ LXI D,SIGNON MVI C,9 CALL BDOS AGIN: MVI C,1 CALL BDOS CPI 3 JZ EXITCPM CPI 13 JNZ AGIN L***** ORG 100H ; ; JMP VECTOR ;************************************************************ HOME: JMP DUMYADR SELDSK: JMP DUMYADR SETTRK: JMP DUMYADR SETSEC: JMP DUMYADR SETDMA: JMP DUMYADR READ: JMP DUMYADR WRITE: JMP DUMYADR ;**************** RUNTYP: JMP BUFMSR ;THIS ROUTINE SETS UP THE PARAMETERS FOR THE COPY ROUTINE. ;COPY CAN BE USED TO TRANSFER: SYS TRACKS 0- 1 ; DAT TRACKS 2-76 ; ALL TRACKS 0-76 ;THE ROUTINE SEARCHES THE DEFAULT BUFFER AT 80H FOR THE ;RUN PARAMETER TO BER COUNT CPI 10 RNZ MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL LXI D,MESGC CALL BDOS XRA A RET ; DMASET: PUSH B MOV C,L MOV B,H CALL SETDMA POP B RET ; ; READT: LXI H,BUF0 ;TRACK # IN C RT2: SHLD DMAAD CALL DMASET CALL SETTRKFOR LSN RAR ;SHIFT MSNIBLE TO LSN RAR RAR RAR CALL PRTNBL ;PRINT IT POP PSW ;NOW FOR LSN PRTNBL: ANI 0FH ADI 30H ;SHIFT TO ASCII VALUE CPI 3AH ;OVER 9? JC SML ADI 7 ;SHIFT TO ALPHA SML: MOV E,A ;FOR BDOS CALL MVI C,2 ;WRITE CONSOO BIOS PRIMITIVES BASE EQU 0 ;FIND WBOOT JMP ADDRESS AT RST0 DUMYADR EQU 0 ;WHO CARES? ; LHLD BASE+1 ;GET WBOOT ADDRESS SPHL ;SAVE IT IN SP FOR DAD ; LXI H,15H DAD SP SHLD HOME+1 ; LXI H,18H DAD SP SHLD SELDSK+1 ; LXI H,1BH DAD S,BUF0 LXI D,BUF1 LXI B,128*LASTSEC CMPLP: LDAX D CMP M JNZ CERR INX H INX D DCR C JNZ CMPLP DCR B ;ARE WE AT END OF BUFFER? JNZ CMPLP RET CERR: PUSH B LXI D,MESGA MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL CALL BDOS LDA TRK *********************************************** ;EQUATES EXITCPM EQU 0 LASTSEC EQU 26 BDOS EQU 5 ;************************************************************ ; MESGA: DB 0DH,0AH,'+COMPARE ERROR ON TRACK $' MESGB: DB '(HEX) SECTOR $' MESGC: DB 'PEWT2: SHLD DMAAD CALL DMASET CALL SETTRK MVI C,1 WT3: PUSH B CALL SETSEC CALL WRITE RAR ;WAS A BIT 0 SET BY DISK ERROR? CC FAILW LHLD DMAAD LXI D,128 DAD D SHLD DMAAD CALL DMASET POP B MVI A,LASTSEC CMP C RZ INR C JMP W MVI C,1 RT3: PUSH B CALL SETSEC CALL READ RAR ;WAS A BIT 0 SET BY DISK ERROR? CC FAILR LHLD DMAAD LXI D,128 DAD D SHLD DMAAD CALL DMASET POP B MVI A,LASTSEC CMP C RZ INR C JMP RT3 ; ; WRITET: LXI H,BUF0 ;TRACK # IN C LE FUNCTION CALL BDOS RET ; ; COPY: MVI C,0 CALL SELDSK ;SELECT DISK A LDA TRKSRT ;FIRST TRACK TO MOVE STA TRK ;MAKE CURRENT MOV C,A CALL SETTRK ;AND SELECT IT ON DISK A MVI C,1 CALL SELDSK ;ALSO B LDA TRKSRT ;FIRST TRACK TO MOVE MP SHLD SETTRK+1 ; LXI H,1EH DAD SP SHLD SETSEC+1 ; LXI H,21H DAD SP SHLD SETDMA+1 ; LXI H,24H DAD SP SHLD READ+1 ; LXI H,27H DAD SP SHLD WRITE+1 ; LXI SP,STKTOP ; ;*********************************************************CALL PRTHEX LXI D,MESGB MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL CALL BDOS POP H ;PUSHED FROM B DAD H ;COMPUTE SECTOR IN ERROR LXI D,0FF00H DAD D MVI A,27 SUB H CALL PRTHEX ;PRINT SECTOR LDA CMPERR INR A STA CMPERR ;INCREMENT ERRORMANENT $' MESGD: DB '+PERMANENT SOURCE DISK ERROR EXIT $' MESGE: DB '+PERMANENT DESTINATION DISK ERROR EXIT $' SIGNON: DB 13,10,'+SOURCE ON A' DB 13,10,'+OBJECT ON B' SINOFF: DB 13,10,'+TYPE $' CRLF: DB 13,10,'$' ; ; PRTHEX: PUSH PSW ;SAVE T3 CMPERR: DB 0 ;NUMBER OF COMPARE ERRORS TRK: DB 0 DMAAD: DS 2 STK: DS 32 STKTOP: DB 0 ; ; ; ; BUF0: DS 128*LASTSEC BUF1: DS 128*LASTSEC ;************************************************************ VECTOR: ;SET UP JUMP VECTORS FOR ACCESS T C,A CALL COMPT ;REREAD AND COMPARE JNZ RETRYW ;RETRY IF ERR LDA TRK INR A STA TRK LXI H,TRKSRT+1 ;POINT TO LAST TRACK+1 STORAGE CMP M ;ARE WE DONE? JNZ RDLOOP ;LOOP IF NOT RET ; ; COMPT: LXI H,BUF1 CALL RT2 ;REREAD INTO BUF1 LXI HOV C,A CALL SETTRK ;AND SELECT IT ON DISK B RDLOOP: MVI C,0 XRA A STA CMPERR CALL SELDSK LDA TRK ;GET TRACK MOV C,A CALL READT ;READ ENTIRE TRACK RETRYW: MVI C,1 CALL SELDSK LDA TRK MOV C,A CALL WRITET ;WRITE TRACK LDA TRK MOV USED ;************************************************************ ;ROUTINE EQUATES TBUFF EQU 80H ;************************************************************ ;DATA TABLES SYSMSG: DB 'YSTEM$' ;SYSTEM MESSAGE DATMSG: DB 'ATA$' ;DATA MESSAGE ALLMSUFF+3 LDAX D CMP M ;SAME AS MESSAGE? JNZ BADMSG INX H INX D DCR C ;REDUCE CHARACTER COUNTER RZ ;FINISHED OK JMP MSGTST+3 ;CHECK OUT NEXT CHARACTER ;************************************************************ BADMSG: LXI D,CMDER1 MVET MESSAGE SIZE JZ NOMSG ;NONE FOUND INX H ;ADD FOR ADDR. PAST MESSAGE MVI B,0 ;EMPTY FOR DAD MOV C,A DAD B ;ADD CHARACTER COUNT TO HL MVI M,'$' ;END BUFFER CHARACTER ;************************************************************ ;NEXT ISR: SHLD TRKSRT ;PUT PARAMETERS IN TRKSRT AND TRKSRT+1 ;************************************************************ LXI D,SIGNON MVI C,9 CALL BDOS AGIN: MVI C,1 CALL BDOS CPI 3 JZ EXITCPM CPI 13 JNZ AGIN LXI D,CRLF MVI C,9 CALL BDOG: DB 'LL$' ;ALL MESSAGE TRKSRT: DW 0 ;STORAGE FOR FIRST AND LAST+1 TRACK NUMBERS CMDER1: DB '+COMMAND "COPY$' CMDER2: DB '" HAS SYNTAX ERROR',0DH,0AH,'$' CMDINF: DB '+THIS PROGRAM IS INITIATED WITH THE COMMAND',0DH,0AH DB '+"COPY SYSTEM", "COPY DAGD JMP DIE FAILW: LXI D,MESGE MVI C,9 ;BDOS PRINT BUFFER FUNCTION CALL DIE: CALL BDOS ;************************************************************ EXIT: LXI D,SINOFF MVI C,9 CALL BDOS MVI C,1 CALL BDOS CPI 13 JNZ EXIT JMP EXITCPM I C,9 CALL BDOS LXI D,TBUFF+1 ;PRINT ERRONEOUS COMMAND MVI C,9 CALL BDOS LXI D,CMDER2 MVI C,9 CALL BDOS NOMSG: LXI D,CMDINF MVI C,9 CALL BDOS JMP EXITCPM ;************************************************************ FAILR: LXI D,MES A TEST FOR WHICH MESSAGE IS PRESENT LDA TBUFF+2 ;FIRST CHARACTER ADDRESS CPI 'S' JZ SYSSET CPI 'D' JZ DATSET CPI 'A' JZ ALLSET JMP BADMSG ;FIRST CHARACTER NOT ONE OF 3 PERMITTED ;*********************************************************S ;************************************************************ CALL COPY ;MAIN ROUTINE LXI D,DONMSG ;SAY WE'RE DONE MVI C,9 CALL BDOS JMP EXIT ;DONE. NOW GET OUT ;************************************************************ MSGTST: LXI H,TBTA" OR "COPY ALL"$' DONMSG: DB '+FUNCTION COMPLETE$' ;************************************************************ ;FIRST WE MEASURE THE INPUT BUFFER MESSAGE ;AND DELIMIT IT WITH A $ PER BDOS CALL 9 BUFMSR: LXI H,TBUFF XRA A ;CLEAR ACC. ADD M ;GEND *************************** EXIT: LXI D,SINOFF MVI C,9 CALL BDOS MVI C,1 CALL BDOS CPI 13 JNZ EXIT JMP EXITCPM FIRST TRACK TO TRANSFER MVI H,77 ;LAST TRACK PLUS ONE JMP PUTPAR ;************************************************************ ALLSET: LXI D,ALLMSG MVI C,3 CALL MSGTST MVI L,0 ;FIRST TRACK TO TRANSFER MVI H,77 ;LAST TRACK PLUS ONE PUTPA*** SYSSET: LXI D,SYSMSG MVI C,6 CALL MSGTST MVI L,0 ;FIRST TRACK TO TRANSFER MVI H,2 ;LAST TRACK PLUS ONE JMP PUTPAR ;************************************************************ DATSET: LXI D,DATMSG MVI C,4 CALL MSGTST MVI L,2 ;;THIS IS A DRIVER TO MAKE A DIABLO/QUME PRINTER ;SIMULATE A SERIAL PRINTER. IT WAS CODED FOR ;A SET OF PARALLEL PORTS STARTING AT 20H, AND ;USES 10 PITCH CARRIAGE MOVES. THE ROUTINE ;ACCUMULATES CARRIAGE POSITION TO PERMIT CR, BUT ;A TAB MOD/8 ROUTINECPI DEL ;DELETE? JZ PDONE ;DISCARD IT CPI LF ;TRAP LF JZ STDPF CPI CR ;TRAP CR JZ PCRET CPI SPACE ;TRAP SPACES JZ STDCM JC PDONE ;SOME OTHER CONTROL CHR. ? ;FOUND A CHARACTER RLC OUT LSB PT1: IN PSTAT ;PRINTER READY? ANI 1 JNZ PT1**** ;MODIFIED FOR ROM AT 0E120H ;WITH 2 BYTES RAM NEEDED AT 47H & 48H ;9/28/77 - A.R.G ; ;QUME OR DIABLO TTY SIMULATOR. ; ;FOR NON-STANDARD ;MOVES, ENTER WITH BC EQUAL TO DISPLACEMENT IN ;APPROPRIATE LSB VALUE (SEE EQU'S BELOW). THEN ;CALL THE ' PT3: IN PSTAT ;PRINTER READY? ANI 4 JNZ PT3 OUT PFST ;YES, OUT STROBE JMP PDONE ; PCRET: LHLD CMACC ;GET POSITION MOV C,L ;MOVE LOW BYTE IN C MOV A,H ;HIGH BYTE IN A ORI 8 ;SET BIT 3 MOV B,A ;PUT INTO B JMP OUT1 ;OUTPUT PORT # FOR MOST SIGNIFICANT BITS OF DATA PSTAT EQU 20H ;INPUT PORT # FOR PRINTER STATUS CHST EQU 22H ;OUTPUT PORT # FOR CHARACTER STROBE CMST EQU 23H ;OUPUT PORT # FOR CARRIAGE MOTION STROBE PFST EQU 24H ;OUTPUT PORT # FOR PAPER FEED STROBE RE WAS NOT INCORPORATED, AS THIS ;ALREADY EXISTED IN THE MAIN PRINT PROGRAM BY ;JEFF KRAVITZ. ;BASED ON A ORIGINAL BY DON IMBIMBO, MODIFIED ;BY A.R.G 6/77 ;************************************************************ ;(HINT - A.R.G) ;ROUTINE CAN BE COCMST ;YES. OUT CARRIAGE MOTION STROBE LHLD CMACC ;GET PRIOR CARRIAGE POSITION MOV A,B ANI 8 ;MASK DIRECTION BIT JNZ LEFT ;MOVE LEFT IF SET DAD B ;ADD MOVE TO CMACC JMP STORE ; LEFT: MOV A,B ;THIS IS A 16 BIT ANI 7 ;SUBTRACT FOR LEFT CMA OUT CHST ;YES. PRINT IT JMP STDCM ;MOVE CARRIAGE ONE SPACE ; STDCM: LXI B,STDSP ;STANDARD MOVE VALUE ;NON-STANDARD MOTION ENTRY OUT1: MOV A,C ;LOAD UP DATA PORTS OUT LSB MOV A,B OUT MSB PT2: IN PSTAT ;PRINTER READY? ANI 2 JNZ PT2 OUT NON-STANDARD' MOVE ENTRY POINT. ;FORMAT FOR CALL IS AS FOLLOWS: ;CARRIAGE MOTION: ;D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 ;NU DIR. /--------------------DATA--------------------------/ ; ;PRINT DATA: ;D4 D3 D2 D1 D0 SET EQU 25H ;OUTPUT PORT # FOR PRINTER RESET CMACC EQU 47H ;USE 47H & 48H FOR RAM SPACE ;************************************************************ ORG 0E120H ;ROUTINE: TTY: PUSH PSW PUSH B PUSH H MOV A,C ;GET CHARACTER FROM CPM HAND-OFF NSIDERABLY SPEEDED IF A SUBROUTINE ;WERE TO BE ADDED WHICH ACCUMULATES SPACES (AND LINE FEEDS) ;UNTIL A PRINTING CHARACTER WAS REQUIRED, AND THEN MOTION(S) ;FOR THE TOTAL DISPLACEMENT(S) CALLED. ;********************************************************;MOVE FROM CMACC MOV B,A MOV A,C CMA MOV C,A INX B DAD B STORE: SHLD CMACC ;AFTER SUB, SAVE ; PDONE: POP H POP B POP PSW RET STDPF: LXI B,STDLF OUT2: MOV A,C RLC ;MOVE LEFT FOR OUT LSB ;PRINTER ONE BIT MOV A,B RAL OUT MSB ;************************************************************ ;EQUATES STDSP EQU 12 ;IN 1/120 INCH STDLF EQU 8 ;IN 1/48 INCH CR EQU 0DH LF EQU 0AH SPACE EQU 20H DEL EQU 7FH LSB EQU 20H ;OUTPUT PORT # FOR LEAST SIGNIFICANT BITS OF DATA MSB EQU 21H D7 D6 D5 D4 D3 D2 D1 D0 ;NU NU NU NU NU NU /----------ASCII DATA----------/ ; ;PAPER FEED: ;D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 ;NU NU DIR. /--------------------DATA---------------------/ ; ;8080 DISASSEMBLER BY WARD CHRISTENSEN AS ;DESCRIBED IN DR. DOBBS'S JOURNAL OF FEB 1977 ;EDITED FOR USE WITH CP/M ASSEMBLER BY A.R.G. ; ;SEE SEDIT.ASM FOR COMPANION SYMBOL TABLE ;EDITOR ; ; * DISASSEMBLER MINUS COMMENTS * COMMENTS DELEATED BY DISA ZTYPE POP 6 JMP XO RET1 MVI A,0DH ZTYPE PUSH B MOV B,A IN 0FFH RAL MOV A,B POP B JNC TYPE PUSH H LHLD FILE+2 MOV M,A INX H SHLD FILE+2 PUSH 6 CALL TYPE POP 6 POP H CPI 0DH RNZ PUSH H LHLD LINAD SHLD LINUM DCCALL PROP RAR RAR RAR ANI 07H ORI '0' CALL ZTYPE JMP IXHRT TYPEB CALL PROP CALL REGM CALL COMMA MOV A,M JMP T1B COMMA MVI A,',' JMP ZTYPE PRDBP POP H PRDB MVI A,'D' CALL ZTYPE MVI A,'B' CALL ZTYPE MVI A,' ' CALL ZTYPE MVI A,' ' CALL ZTYPE IN 0FFH ANI ' ' JNZ PRDB PUSH H MOV H,M LXI B,OPTAB ULP LDAX B ORA A JZ PRDBP ANA H MOV L,A INX B LDAX B CMP L JZ FOUND MOV A,C ADI 6 MOV C,A JNC ULP INR B JMP ULP FOUND INX B LDAX B SYPE MVI A,'''' JMP ZTYPE PROP PUSH D MVI D,04H PROPL INX B LDAX B CALL ZTYPE DCR D JNZ PROPL LDAX B CPI ' ' MVI A,' ' CNZ ZTYPE POP D MOV A,M RET XR RAR RAR RAR ANI 6 CPI 6 JNZ REG MVI A,'6' JMP ZTYPE REGM RAR POP 6 MVI A,'''' CALL ZTYPE JMP RET1 TYPE6 CALL PROP MOV A,M CALL XR CALL COMMA JMP TYP6H PRT2X CALL SYMBO JC RET1 TYP6H INX H MOV B,M INX H MOV A,M CALL XO0 MOV A,B CALL XO JMP T54 TYPE7 CALL PROP CALL SYMBO JC RET1 SSEMBLY ORG 3100H FILE EQU 3805H ;MEM FILE START STORED HERE TYPE EQU 409CH ;ASCII OUT FROM A RTN. BBUF EQU 3868H ;ADDR TO START DISAS STORED HERE SYMTB EQU 0C002H ;SYMBOL TABLE AREA SPVR EQU 401FH START IN 0FFH ANI 4 JZ NOSYM XRA A STA SYMTTA CC1+2 POP H LXI B,TYFLG MVI A,' ' STA CCB RET CCTAB MOV C,M MOV E,D MOV E,D DB 20H MOV C,M MOV B,E MOV B,E DB 20H MOV D,B MOV C,A MOV D,B MOV B,L MOV D,B DB 20H MOV C,L DB 20H HEXL RAR RAR RAR RAR HEXR AN DCX H IN 0FFH ANI '0' CPI '0' JNZ T52 INX H MOV A,M DCX H CPI ' ' JC T52 CPI 5BH JNC T52 INX H INX H JMP QCHAR GETCC MOV A,M RAR RAR ANI 0EH PUSH H LXI H,CCTAB CALL ADD1 MOV A,M STA CC1+1 INX H MOV A,M STA TYFLG PUSH D MOV E,A MVI D,00H LXI H,JMTBL DAD D DAD D DAD D POP D XTHL RET JMTBL JMP TYPE0 JMP TYPE1 JMP TYPE2 JMP TYPE3 JMP TYPE4 JMP TYPE5 JMP TYPE6 JMP TYPE7 JMP TYPE8 JMP TYPE9 JMP TYPEA JMP TYPEB TYPE0 C RAR RAR REG PUSH H LXI H,RTAB ANI 07H CALL ADD1 MOV A,M POP H JMP ZTYPE ADD1 ADD L MOV L,A RNC INR H RET RTAB DB 'B' DB 'C' DB 'D' DB 'E' DB 'H' DB 'L' DB 'M' DB 'A' XO0 CPI 0A0H JC XO PUSH 6 MVI A,'0' CALL IN 0FFH ANI 08H JZ PRT2X MVI A,'L' CALL ZTYPE INX H MOV B,M INX H MOV A,M CALL XO MOV A,B CALL XO INX H JMP RET1 TYPE8 INX B LDAX B STA CC1 CALL GETCC JMP TYPE7 TYPE9 MVI A,'R' STA CC1 CALL GETCC JMP TYPE0 TYPEA B NOSYM LHLD FILE INX H IN 0FFH ANI 80H JZ NOSTR SHLD FILE+2 NOSTR LHLD BBUF DISAM CALL LINE JMP DISAM LINE PUSH H LHLD FILE+2 SHLD LINAD POP H MOV A,H CALL XO MOV A,L CALL XOB MOV B,H MOV C,L IN 0FFH ANI 1 CNZ PRTLBI 0FH CPI 0AH JC HEXRN ADI 07H HEXRN ADI '0' RET XO PUSH 6 CALL HEXL CALL ZTYPE POP 6 CALL HEXR JMP ZTYPE XOB CALL XO MVI A,' ' JMP ZTYPE OQ PUSH 6 MVI A,' ' CALL ZTYPE MVI A,'''' CALL ZTYPE POP 6 JMP ZTYPE CQ CALL ZT T54 MVI A,'H' CALL ZTYPE MOV A,M INX H PUSH B MOV B,A IN 0FFH ANI 10H MOV A,B POP B JZ RET1 CPI ' ' JC RET1 CPI 5BH JNC RET1 LDA TYFLG CPI 4 JC RET1 CPI 6 JNC RET1 DCX H MOV A,M INX H QCHAR PUSH 6 CALL OQ ALL PROP IXHRT INX H JMP RET1 TYPE1 CALL PROP T1B CALL REG JMP IXHRT TYPE2 CALL PROP CALL REGM JMP IXHRT TYPE3 CALL PROP CALL XR JMP IXHRT TYPE4 CALL PROP CALL REGM CALL COMMA JMP T52 TYPE5 CALL PROP T52 INX H MOV A,M CALL XO0X H MOV A,H CMA MOV D,A MOV A,L CMA MOV E,A INX D LHLD FILE+2 DAD D MOV A,L LHLD LINAD DCX H MOV M,A LHLD FILE+2 SHLD LINAD INX H SHLD FILE+2 MOV A,H CPI '0' POP H JNZ CKX END1 LHLD FILE+2 DCX H MVI M,01H SH OF CUR LINE'S LINE # TYFLG DS 1 ;OP CODE TYPE CC1 DS 3 ;CONDITION STORED HERE CCB DS 1 ;BLANK FOLLOWING COND CODE END &" DB 0FFH DW 0FBH DW 'IE' DW ' ' DB 0FFH DW 0F9H DW 'PS' DW 'LH' DB 0FFH DW 5C6H DW 'DA' DW ' I' DB 0FFH DW 5CEH DW 'CA' DW ' I' DB 0FFH DW 5D6H DW 'US' DW ' I' DB 0FFH DW 5DEH DW 'BS' DW ' I' DB 0FFH DW 5 MOV B,M DCX H DCX H CALL LOOKU RNC MVI A,'L' STAX D INX D MOV A,B CALL SYSTX MOV A,C CALL SYSTX MOV A,B STAX D INX D MOV A,C STAX D XRA A INX D STAX D STC RET SYSTX PUSH 6 CALL HEXL STAX D INX D POP 6 'NI' DW ' X' DB 0CFH DW 309H DW 'AD' DW ' D' DB 0CFH DW 30BH DW 'CD' DW ' X' DB 0C7H DW 8C2H DW '.J' DW '..' DB 0C7H DW 8C4H DW '.C' DW '..' DB 0CFH DW 601H DW 'XL' DW ' I' DB 0C7H DW 9C0H DW '.R' DW '..' FH DW 73AH DW 'DL' DW ' A' DB 0FFH DW 3FH DW 'MC' DW ' C' DB 0FFH DW 76H DW 'LH' ;HLT PRECEEDS MOV TO DW ' T' ;PREVENT 'MOV M,M' DB 0C0H DW 0B40H DW 'OM' DW ' V' DB 0FFH DW 7C3H DW 'MJ' DW ' P' DB 0FFH DW 0C9H DWLD FILE+2 LHLD LINUM MVI B,04H LXI D,FILE+4 MOVLN MOV A,M STAX D INX H INX D DCR B JNZ MOVLN JMP SPVR CKX IN 1 ANI 7FH CPI 'X'-40H RNZ JMP END1 SYMBO IN 0FFH ANI 05H RZ ANI 1 JNZ FRMTB CALL SYBLD ORA A RET FRMTB DW ' B' DB 0F8H DW 198H DW 'BS' DW ' B' DB 0F8H DW 1A0H DW 'NA' DW ' A' DB 0F8H DW 1A8H DW 'RX' DW ' A' DB 0F8H DW 1B0H DW 'RO' DW ' A' DB 0F8H DW 1B8H DW 'MC' DW ' P' DB 0C7H DW 204H DW 'NI' DW ' R' DB 0C7E6H DW 'NA' DW ' I' DB 0FFH DW 5EEH DW 'RX' DW ' I' DB 0FFH DW 5F6H DW 'RO' DW ' I' DB 0FFH DW 5FEH DW 'PC' DW ' I' DB 0F8H DW 180H DW 'DA' DW ' D' DB 0F8H DW 188H DW 'DA' DW ' C' DB 0F8H DW 190H DW 'US' CALL HEXR STAX D INX D RET LOOKU LXI D,0C002H LULP LDAX D ORA A STC RZ INX D INX D INX D INX D INX D LDAX D CMP B INX D JNZ LUNO LDAX D CMP C JNZ LUNO DCX D DCX D DCX D DCX D DCX D DCX D ORA A RET LUNO DB 0C7H DW 0AC7H DW 'SR' DW ' T' DB 0 ;(END OF TABLE) *----------WORK AREA----------* * NOTE: DISASSEMBLER IS ROM-ABLE * (= PROTECTABLE) IF THIS AREA * IS MOVED TO READ-WRITE MEMORY. LINAD DS 2 ;ADDR OF START OF CUR LINE LINUM DS 2 ;ADDR 'ER' DW ' T' DB 0FFH DW 7CDH DW 'AC' DW 'LL' DB 0FFH DW 5D3H DW 'UO' DW ' T' DB 0FFH DW 5DBH DW 'NI' DW ' ' DB 0FFH DW 0E3H DW 'TX' DW 'LH' DB 0FFH DW 0E9H DW 'CP' DW 'LH' DB 0FFH DW 0F3H DW 'ID' DW ' ' INX H MOV C,M INX H MOV B,M INX H CALL PRTLB RC DCX H DCX H DCX H ORA A RET PRTLB CALL LOOKU CMC RNC MVI B,05H SYPLP LDAX D INX D ORA A STC RZ CALL ZTYPE DCR B STC RZ JMP SYPLP SYBLD INX H MOV C,M INX H H DW 205H DW 'CD' DW ' R' DB 0EFH DW 302H DW 'TS' DW 'XA' DB 0EFH DW 30AH DW 'DL' DW 'XA' DB 0CFH DW 3C1H DW 'OP' DW ' P' DB 0CFH DW 3C5H DW 'UP' DW 'HS' DB 0C7H DW 406H DW 'VM' DW ' I' DB 0CFH DW 303H DW' DW ' R' DB 0FFH DW 722H DW 'HS' DW 'DL' DB 0FFH DW 27H DW 'AD' DW ' A' DB 0FFH DW 72AH DW 'HL' DW 'DL' DB 0FFH DW 2FH DW 'MC' DW ' A' DB 0FFH DW 732H DW 'TS' DW ' A' DB 0FFH DW 37H DW 'TS' DW ' C' DB 0F INX D JMP LULP *@2A0-3 * OPTAB DB 0FFH DW 0 DW 'ON' DW ' P' DB 0FFH DW 7 DW 'LR' DW ' C' DB 0FFH DW 0FH DW 'RR' DW ' C' DB 0FFH DW 17H DW 'AR' DW ' L' DB 0FFH DW 0EBH DW 'CX' DW 'GH' DB 0FFH DW 1FH DW 'AR ;REF. NO. AB22 ;PROGRAM NAME DISASM (8080 DISASSEMBLER) ; ;(FROM INTEL LIBRARY??) ; ; ; ; ORG 1B00H CO EQU 3809H RDBYTE: LHLD PC MOV A,M INX H SHLD PC RET RGPRNT: INR A ANI 07 CPI 06 JC RGP1 ADI 03 RGP1: CPI 05 JC RGP2: LXI H,PMOV CALL PRINT CALL XTRACT CALL RGPRNT MVI C,2CH CALL CO D9: MOV A,D ANI 07 CALL RGPRNT JMP DISASM TG3: MOV A,C ADD A ADD A MOV C,A LXI H,TAB3-4 DAD B CALL PRINT D7: CALL RDBYTE MOV D,A CALL RDBYTE CALL DECODE NT: CALL XTRACT ANI 06 CPI 06 JNZ RGPRNT MVI C,53H CALL CO MVI C,50H JMP CO DISASM: MVI C,0DH CALL CO MVI C,0AH CALL CO LHLD PC MOV A,H CALL DECODE MOV A,L CALL DECODE MVI C,20H CALL CO CALL CO CALL RDBYTE MOV D,A'STA ' DB 'LHLD','SHLD' 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 ','STAX','INX ','DAD ' DB 'LDAX','DCX ' PRST: DB 'RST JMP DISASM MG5: LXI H,PLXI MOV A,D ANI 0FH DCR A JZ MG51 CPI 04 JC D4 SUI 05 D4: ADD A ADD A MOV C,A DAD B CALL PRINT CALL RPPRNT JMP DISASM MG51: CALL PRINT CALL RPPRNT MVI C,2CH CALL CO JMP D7 MG4: LXI H,PMVI C ADI 02 RGP2: ADI 41H MOV C,A JMP CO DECODE: MOV B,A ANI 0F0H RRC RRC RRC RRC ADI 90H DAA ACI 40H DAA MOV C,A CALL CO MOV A,B ANI 0F0H ADI 90H DAA ACI 40H DAA MOV C,A JMP CO PRINT: MVI B,4 P1: MOV C,M TABLE: DB 000H,007H,00FH,017H DB 01FH,027H,02FH,037H DB 03FH,076H,0C9H,0E3H DB 0E9H,0EBH,0F3H,0F9H DB 0FBH,0C6H,0CEH,0D3H DB 0D6H,0DBH,0DEH,0E6H DB 0EEH,0F6H,0FFH,022H DB 02AH,032H,03AH,0C3H DB 0CDH TAB1: DB 'EI ','SPHL','DI ','XCHG' MOV A,D CALL DECODE JMP DISASM TG2: MOV A,C ADD A ADD A MOV C,A LXI H,TAB2-4 DAD B CALL PRINT D8: CALL RDBYTE CALL DECODE JMP DISASM TG1: MOV A,C ADD A ADD A MOV C,A LXI H,TAB1-4 DAD B CALL PRINT JMP DISASM PC: DS 2 LXI H,TABLE LXI B,11H D1: CMP M JZ TG1 INX H DCR C JNZ D1 MVI C,0AH CMP M 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 ANIT ' PPSW: DB 'PSW ' PPOP: DB 'POP ','PUSH' CCODE: DB 'NZ','Z ','NC','C ' DB 'PO','PE','P ','M ' END  PINR: DB 'INR ' PDCR: DB 'DCR ' PMVI: DB 'MVI ' PLXI: DB 'LXI ','STAX','INX ','DAD ' DB 'LDAX','DCX ' PRST: DB 'RSALL PRINT CALL XTRACT CARGPRNT MVI C,2CH CALL CO JMP D8 MG3: LXI H,PDCR JMP D5 MG2: LXI H,PINR D5: CALL PRINT CALL XTRACT D6: CALL RGPRNT JMP DISASM MG1: MOV A,D ANI 38H RRC MOV C,A LXI H,PADD DAD B CALL PRINT JMP D9 MG0 CALL CO INX H DCR B JNZ P1 MVI C,20H JMP CO XTRACT: MOV A,D ANI 38H RRC RRC RRC RET CCPRNT: CALL XTRACT 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 RPPR DB 'PCHL','XTHL','RET','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 'CALL','JMP ','LDA ',TRACT CPI 06 JNZ D6 LXI H,PPSW CALL PRINT JMP DISASM MG9: LXI H,PRST CALL PRINT CALL DECODE JMP DISASM MG8: MVI C,43H CALL CO CALL CCPRNT JMP D7 MG7: MVI C,4AH CALL CO CALL CCPRNT JMP D7 MG6: MVI C,52H CALL CO CALL CCPRN 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 X ORG 100H ;THE FOLLOWING EQU MUST BE CHANGED FOR USE ON ;OTHER THAN 16K SYSTEMS CBBASE EQU 3E00H CONOUT EQU CBBASE+0CH CONIN EQU CBBASE+9 LASTSEC EQU 26 GO: LXI SP,STKTOP LXI D,MESGA CALL CRPRT CALL GETCON ANI 1 ;GET LSB FOR DISK SELECT SK NUMBER DUMMY EQU DISKNO+1 ;MUST BE 0 FOR DOUBLE ADD ; ; ; ; ; I/O DRIVERS FOR THE DISK FOLLOW ; HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE LDA DISKNO ;SELECTED DISK MOV C,A ;FOLLOW PARAMETER CONVENTIONS CALL SELDSK ;ROUTINE TO SC JNZ FLP DCR B JNZ FLP RET ; ; ; ; COMPT: LXI H,BUF1 CALL RT2 ;REREAD INTO BUF1 LXI H,BUF0 LXI D,BUF1 LXI B,128*LASTSEC CMPLP: LDAX D CMP M JNZ CERR INX H INX D DCR C JNZ CMPLP DCR B ;ARE WE AT END OF BUFFER? JNZ CMPLSELECT DRIVE TO TEST, A OR B? $' MESGB: DB 'INSERT SCRATCH DISKETTE, THEN RETURN $' MESGC: DB 'COMPARE ERROR ON TRACK $' MESGD: DB '(HEX) SECTOR $' MESGE: DB 'PERMANENT $' MESGF: DB 'REPEAT TEST CONTINUOUSLY OR STOP? (R OR S) $' MESGG: DB 'INSERT SYSTKTOP: DB 0 ORG 400H ;KEEP CONSTANT ; TRACK = LAST SELECTED TRACK ; SECTOR = LAST SELECTED SECTOR ; DMAAD = LAST SELECTED DMA ADDRESS ; DISKNO = LAST SELECTED DISK NUMBER ; (NOTE THAT ALL ARE BYTE VALUES EXCEPT FOR DMAAD) ; SCRAT DB C,0DH CALL CONOUT MVI C,0AH CALL CONOUT RET ; PRTHEX: PUSH PSW RAR RAR RAR RAR CALL PRTNBL POP PSW PRTNBL: ANI 0FH ADI 30H CPI 3AH JC SML ADI 7 SML: MOV C,A CALL CONOUT RET ; FILDSK: CALL FILBUF0 XRA A FDLP: PUSHXRI 1 ;ASCII A MEANS SELECT 0 MOV C,A CALL SELDSK LXI D,MESGB CALL CRPRT CALL CONIN CALL HOME LXI D,MESGF CALL CRPRT CALL GETCON STA REPEAT GOTEST: CALL TEST LDA REPEAT ANI 0DFH ;CONVERT TO UPPER CASE CPI 'R' ;LOOP IF REPEAT FL0 ;TRACK # IN C RT2: SHLD DMAAD CALL SETTRK MVI C,1 RT3: PUSH B CALL SETSEC CALL READ LHLD DMAAD LXI D,128 DAD D SHLD DMAAD POP B MVI A,LASTSEC CMP C RZ INR C JMP RT3 ; ; WRITET: LXI H,BUF0 ;TRACK # IN C WT2: SHLD DMAAD P RET CERR: PUSH B LXI D,MESGC CALL CRPRT LDA TRK CALL PRTHEX LXI D,MESGD CALL PRTMSG POP H ;PUSHED FROM B DAD H ;COMPUTE SECTOR IN ERROR LXI D,0FF00H DAD D MVI A,27 SUB H CALL PRTHEX ;PRINT SECTOR RET ; ; READT: LXI H,BUFTEM DISK, THEN RETURN $' MESGH: DB 'DO YOU WANT TO RESTART THIS TEST? (Y OR N) $' MESGI: DB 'COMPLETED TEST LOOP $' ; TEST: MVI A,0 ;TEST PATTERN CALL FILDSK CALL SKTST ;SEEK TEST MVI A,0FFH CALL FILDSK MVI A,55H CALL FILDSK MVI A,0AAH0,0,0,0,0,0,0,0,0,0,0 ;START OF SCRATCH AREA TRACK EQU SCRAT ;CURRENT TRACK ON DRIVE 0 TRAK1 EQU TRACK+1 ;CURRENT TRACK ON DRIVE 1 SECTOR EQU SCRAT+2 ;CURRENTLY SELECTED SECTOR DMAAD EQU SCRAT+3 ;CURRENT DMA ADDRESS DISKNO EQU SCRAT+5 ;CURRENT DI PSW MOV C,A STA TRK CALL WRITET ;WRITE ONE TRACK POP PSW PUSH PSW MOV C,A CALL COMPT POP PSW INR A CPI 77 JNZ FDLP ;DO ALL 77 TRACKS RET ; FILBUF0: LXI H,BUF0 ;FILL BUF0 WITH (A) LXI B,128*LASTSEC FLP: MOV M,A INX H DCR AG ON JZ GOTEST LXI D,MESGH CALL CRPRT CALL GETCON ANI 0DFH ;CONVERT TO UPPER CASE CPI 'Y' JZ GO LXI D,MESGG CALL CRPRT CALL CONIN JMP 0 ;REBOOT ; GETCON: CALL CONIN PUSH PSW MOV C,A CALL CONOUT POP PSW RET ; MESGA: DB 'CALL SETTRK MVI C,1 WT3: PUSH B CALL SETSEC CALL WRITE LHLD DMAAD LXI D,128 DAD D SHLD DMAAD POP B MVI A,LASTSEC CMP C RZ INR C JMP WT3 REPEAT: DB 0 CMPERR: DB 0 ;NUMBER OF COMPARE ERRORS TRK: DB 0 TSTCNT: DB 0 STK: DS 32 SI 77 JZ SKDONE PUSH PSW MOV C,A CALL READT ;READ INCREASING TRACK NO JMP SKLP SKDONE: RET ; ; CRPRT: CALL CRLF PRTMSG: LDAX D ;GET CHAR INX D CPI '$' RZ PUSH D MOV C,A CALL CONOUT POP D JMP PRTMSG ;LOOP TILL $ ; CRLF: MVI CALL FILDSK MVI A,0E5H CALL FILDSK CALL SKTST LXI D,MESGI CALL CRPRT LDA TSTCNT INR A STA TSTCNT CALL PRTHEX RET ; ;SEEK TEST ; SKTST: XRA A PUSH PSW SKLP: XRA A MOV C,A CALL READT ;READ TRACK ZERO POP PSW INR A CPELECT THE DISK ;SET UP H,L TO POINT TO WORD WITH TRACK FOR SELECTED DISK LXI D,TRACK LHLD DISKNO DAD D HOMEL: MVI M,00 ;SET CURRENT TRACK PTR BACK TO 0 IN 127 ;READ FDC STATUS ANI 4 ;TEST TRACK 0 BIT RNZ ;RETURN IF AT 0 STC ;DIRECTION=OESGE4: DB ', SECTOR $' REDO: POP D ;GET R/W FLAG IN 127 ;GET ERROR BITS ANI 0E0H ;RETRY IF NOT TRACK ERROR JNZ TRYAGN ;WAS A TRACK ERROR SO NEED TO RESEEK PUSH D ;SAVE READ/WRITE INDICATOR ;FIGURE OUT THE DESIRED TRACK LXI D,TRACK LHLD DIS A,0 ;SET ERROR COUNT STA ERRORS ;RETRY SOME FAILURES 10 TIMES ;BEFORE GIVING UP TRYAGN: ;FIRST WE HAVE TO FIGURE OUT WHICH DRIVE IS SELECTED ;AND WHICH TRACK IS DESIRED LXI B,TRACK LHLD DISKNO DAD B ;H,L POINT TO CORRECT TRACK INDICATOR MOV A,C ;DESIRED TRACK CMP M RZ ;WE ARE ALREADY ON THE TRACK SETTKX: CALL STEP ;STEP TRACK-CARRY HAS DIRECTION ;STEP WILL UPDATE TRACK INDICATOR MOV A,C CMP M ;ARE WE WHERE WE WANT TO BE JNZ SETTKX ;NOT YET ;HAVE STEPPED ENOUGH SEEKRT: H D ;SAVE READ/WRITE CODE LXI D,MESGE1 CALL CRPRT IN 127 ANI 0F0H CALL PRTHEX LXI D,MESGE2 CALL PRTMSG LDA DISKNO ADI 'A' MOV C,A CALL CONOUT LXI D,MESGE3 CALL PRTMSG LXI D,TRACK LHLD DISKNO DAD D MOV A,M CALL PRTHEX LM THE ACTUAL I/O ; WRITE: ;PERFORM A WRITE OPERATION MVI D,80H ;SET WRITE COMMAND ; WAITIO: ;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O ;OPERATION. RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES ;PROPERLY, AND 01H IF AN ERROUT CALL STEP ;STEP ONE TRACK JMP HOMEL ;LOOP ; SELDSK: ;SELECT DISK GIVEN BY REGISTER C ;MAKE SURE DUMMY IS 0 (FOR USE IN DOUBLE ADD TO H,L) XRA A STA DUMMY MOV A,C STA DISKNO RRC ;PUT INTO BITS 4,5 RRC RRC RRC ORI 08 ;ENABLE DISK ;WILL RESULT IN HEAD UNLOADED ;ERROR, SO DONT CHECK MOV M,A DCX H MOV E,M POP PSW MOV M,A MOV A,H ;SET UP FDC DMA ADDRESS OUT 126 ;HIGH BYTE MOV A,L OUT 125 ;LOW BYTE MOV A,D ;GET R/W FLAG OUT 127 ;START DISK READ/WRITE RWWAOV A,M PUSH PSW ;NEED IT LATER LHLD DMAAD ;GET BUFFER ADDRESS DCX H ;SAVE AND REPLACE 3 BYTES BELOW ;BUF WITH TRACK,SECTOR,ADDRESS MARK MOV B,M MVI A,0FBH ;ADDRESS MARK MOV M,A DCX H MOV C,M LDA SECTOR ;NOTE THAT INVALID SECTOR NUMBER;DELAY 18 MSEC FOR FINAL STEP TIME AND HEAD SETTLE TIME MVI A,18D CALL DELAY RET ;END OF SETTRK ROUTINE ; DELAY: ;ROUTINE TO DELAY C(A) MILLISECONDS MVI C,82H ;ADJUST FOR 1 MSEC LOOP DELAY ;THIS IS THE VALUE FOR OUR IMSAI LDXA: DCR C JNXI D,MESGE4 CALL PRTMSG LDA SECTOR CALL PRTHEX LDA ERRORS INR A STA ERRORS CPI 20 JNZ REDO ;RETRY 20 TIMES POP D MVI A,0FFH ;ERROR RETURN RET ; MESGE1: DB 'DISK ERROR, TYPE $' MESGE2: DB ', ON DRIVE $' MESGE3: DB ', AT TRACK $' MR OCCURS DURING THE READ OR WRITE ; ;IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO' (0,1) ; THE TRACK NUMBER IN 'TRACK' (0-76) ; THE SECTOR NUMBER IN 'SECTOR' (1-26) ; THE DMA ADDRESS IN 'DMAAD' (3-3F80H) ;D STILL HAS R/W FLAG MVI SELECT OUT 127 ;SELECT THE DISK RET ; SETTRK: ;SET TRACK GIVEN BY REGISTER C ;FIRST REFERENCE CORRECT TRACK INDICATOR ACCORDING TO ;SELECTED DISK LXI D,TRACK ;ADDRESS OF TRACK FOR DISK 0 LHLD DISKNO ;FIND OUT WHICH DISK IS SELECTED DAD D MIT: IN 127 ;READ FDC STATUS ANI 0F8H ;TEST FOR ANY ERROR OR IOF JZ RWWAIT MOV M,E ;RESTORE 3 BYTES BELOW BUF INX H MOV M,C INX H MOV M,B IN 127 ;TEST FOR ERRORS ANI 0F0H RZ ;A WILL BE 0 IF NO ERRORS ;COME HERE ON ERROR FROM DISK PUS SHLD DMAAD ;SAVE THE ADDRESS RET ; ; ERRORS: DB 0 ;KEEP TRACK OF NUMBER OF ERRORS READ: ;PERFORM READ OPERATION. ;THIS IS SIMILAR TO WRITE, SO SET UP READ COMMAND AND USE ;COMMON CODE IN WRITE MVI D,40H ;SET READ FLAG JMP WAITIO ;TO PERFORZ LDXA ;LOOP 1 MSEC DCR A JNZ DELAY RET ;END OF DELAY ROUTINE ; SETSEC: ;SET SECTOR GIVEN BY REGISTER C MOV A,C STA SECTOR RET ; SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C MOV L,C ;LOW ORDER ADDRESS MOV H,B ;HIGH ORDER ADDRESSKNO ;SELECTED DISK DAD D ;POINT TO CORRECT TRACK INDICATOR MOV A,M ;DESIRED TRACK PUSH PSW ;SAVE IT CALL HOME POP PSW MOV C,A CALL SETTRK POP D ;GET READ/WRITE INDICATOR JMP TRYAGN ; ; ; STEP: ;STEP HEAD OUT TOWARDS ZERO ;IF CATCH 2 ' HT MESSAGE TO GIVE ; CLUE OF REVISION IN OBJECT CODE ; NOTICE EQU 106H ; ORG NOTICE ; DB '(C) 1976, DIGITAL RESEARCH. PT. MOV A,C ;WRITE CHECKSUM. CASW: PUSH PSW ;SAVE DATA ON STACK. CALP: IN CASC ;READ CASSETTE STATUS. ANI 20H ;LOOK AT BIT 5. JNZ CALP ;WAIT UNTIL READY. POP PSW ;RECOVER DATA. OUT CASD ;WRITE A BYTE. ADD C ;ADD TO CHECKSUM. MOV C, JMP DOSTEP ; ; ; BUF0: DS 128*LASTSEC BUF1: DS 128*LASTSEC END 27 ;PULSE STEP BIT ANI 0FDH OUT 127 ;TURN OFF PULSE RET ; OUTX: DCR M ;UPDATE TRACK BYTE XRA A ;SET DIRECTION = OUT 3H ;BODY OF PATCH ; ; ORG JMPOUT JMP PATCH ; ORG PATCH LXI B,TBUFF ;SET DMA TO 80H CALL SETDMA LXI B,14D1H ;CLOBBERED BY JMP PATCH JMP JMPOUT+3 ; ; PATCH BY JOHN HENDERSON TO FIX THE CONVERSION ; OF INSERTION MATERIAL BY R COMMAND INTO Y: MVI A,3CH ;WRITE START BYTE. CALL CASW DCX D ;DECREMENT COUNT. MOV A,D ;IF D&E ARE ORA E ;YET ZERO, JNZ DELAY ;KEEP COUNTING DOWN. MVI A,0E6H ;WRITE SYNC BYTE. CALL CASW MVI C,0 ;CLEAR CHECKSUM. MVI A,90H ;WRITE TYPE BYTE. ARRY IS SET; ELSE ;STEP IN ; H,L POINT TO CORRECT TRACK INDICATOR WORD PUSH PSW ;SAVE DIRECTION STWAIT: IN 127 ;INPUT FDC STATUS ANI 2 ;TEST STEP READY BIT JZ STWAIT ;WAIT FOR STEP READY(MAX 10 MSEC) POP PSW ;GET DIRECTION TO STEP JC OUTX A RET ;RETURN FROM CASW. CASC: EQU 6EH ;CASSETTE STATUS PORT. CASD: EQU 6FH ;CASSETTE DATA PORT. BIT 5. JNZ CALP ;WAIT UNTIL READY. POP PSW ;RECOVER DATA. OUT CASD ;WRITE A BYTE. ADD C ;ADD TO CHECKSUM. MOV C,; DSKCAS - TRANSFER DISK TO CASSETTE ; TARBELL ELECTRONICS ; ORG 100H FDOS: EQU 5 ;DISK SYSTEM ENTRY POINT. TFCB: EQU 5CH ;DEFAULT FILE CONTROL BLOCK. TBUFF: EQU 80H ;DEFAULT BUFFER LOCATION. MVI C,15 ;OPEN FILE. LXI D,TFCB CALL FDOS UPPER ; CASE. RETURN BEFORE CALLING ROUTINE AT 05E9H. ; PATCH2 EQU 06ECH ; ORG PATCH2 RET ; ; PATCH TO CHANGE COPYRIGHT MESSAGE TO GIVE ; CLUE OF REVISION IN OBJECT CODE ; NOTICE EQU 106H ; ORG NOTICE ; DB '(C) 1976, DIGITAL RESEARCH. PCALL CASW MOV A,B ;WRITE LENGTH BYTE. CALL CASW MOV A,B ;GET LENGTH BYTE. ORA A ;IF IT'S ZERO, RZ ;RETURN FROM CTWT. CTLP: MOV A,M ;WRITE DATA BYTE. CALL CASW INX H ;INCREMENT POINTER. DCR B ;DECREMENT COUNTER. JNZ CTLP ;REPEA INR M ;INCREMENT CURRENT TRACK BYTE MVI A,4 ;SET DIRECTION = IN DOSTEP: OUT 127 ;SET DIRECTION BIT IN FDC ORI 2 OUT 127 ;PULSE STEP BIT ANI 0FDH OUT 127 ;TURN OFF PULSE RET ; OUTX: DCR M ;UPDATE TRACK BYTE XRA A ;SET DIRECTION = OUT ; ; PATCH BY DIGITAL RESEARCH TO CORRECT BUG ; IN ED.COM VERS. 1.3 RELATED TO GARBAGE ; INSERTION FROM R COMMAND ; SETDMA EQU 257H ;ADDRESS OF SET DMA ROUTINE TBUFF EQU 80H ;DEFAULT BUFFER ADDRESS JMPOUT EQU 1017H ;ACCESS TO THE PATCH PATCH EQU 13FOF MVI C,16 ;CLOSE FILE. LXI D,TFCB CALL FDOS JMP 0 ;DO A WARM START. ; CTWT - WRITE A BLOCK TO CASSETTE. ; CTWT: MVI B,80H ;LENGTH FOR NORMAL RECORD. EOF: LXI H,TBUFF ;GET ADDRESS OF BUFFER. LXI D,187*2 ;GET COUNT FOR 2 SECONDS. DELAMLOOP: MVI C,20 ;READ A RECORD FROM DISK. LXI D,TFCB CALL FDOS ORA A ;IF READ NOT OK, JNZ CLOSE ;CLOSE FILE. CALL CTWT ;OTHERWISE, WRITE TO CASSETTE. JMP MLOOP ;AND GET ANOTHER FROM DISK. CLOSE: MVI B,0 ;WRITE END-OF-FILE MARK. CALL E;*********************************; ; EXAMINE UTILITY ; ;*********************************; ORG 100H ;**** ; MISC. EQUATES ;**** TBUF EQU 0080H VDMLC EQU 0CC00H ;***** ; OBTAIN BIOS VECTORS ;***** VECTRS: JMP GETVEC DS XN ;CONVERT INX H ;BUMP MEM ADDRESS RET HXN: ANI 0FH ;GET 4 BITS ORI 30H ;CONVERT TO ASCII CPI 3AH ;A-F? JC HXN1 ;NO, CONTINUE ADI 07 ;COMPENSATE HXN1: MOV M,A ;STORE BYTE RET MOVE: LDAX D MOV M,A INX H INX D DCR B JNZ MOVE UF ;POINT TO BUFFER MVI C,128 ;BUFFER SIZE DL3: LDAX D ;GET BYTE FROM BUFFER CALL HXO ;DISPLAY BYTE INX D ;BUMP BUFFER POINTER DCR C ;DECREMENT BYTE COUNT JNZ DL3 ;LOOP LXI H,VDMLC+(14*64) MVI B,64 CALL BLANKIT RET BLANKIT:MVI M,' ' VDM MVI A,' ' CLR: MVI C,00 CL2: MOV M,A INX H DCR C JNZ CL2 DCR B JNZ CLR LXI H,TBUF ;CLEAR BUFFER TO SPACES MVI B,128 ;BUFFER SIZE MVI A,' ' CL3: MOV M,A INX H DCR B JNZ CL3 LXI D,MSG1 LXI H,VDMLC+64 MVI B,64 CALL MOVTG STC RET NXTRK: LDA CURTK CPI 76 CMC RC ;ERROR INR A STA CURTK RET PVSEC: LDA CURSC CPI 01+1 JC PVS2 DCR A STA CURSC XRA A RET PVS2 MVI A,26 STA CURSC STC RET PVTRK: LDA CURTK CPI 00+1 RC DCR A STA CURTK 0 RET ;**** ; DISPLAY ROUTINE ;**** DSPLY: LXI D,TBUF LXI H,VDMLC+256 MVI B,80H CALL MOVE LXI H,VDMLC+128 LXI D,MSG2 MVI B,64 ;MOVE MESSAGE TO SCREEN CALL MOVTG LXI H,VDMLC+128+OF1 ;OFFSET TO FIELD1 LDA CURSC CALL HXO ;DISPLAY 42 WBOOTE EQU VECTRS+3 CSTS EQU VECTRS+6 CI EQU VECTRS+9 CO EQU VECTRS+12 LO EQU VECTRS+15 PO EQU VECTRS+18 RI EQU VECTRS+21 HOME EQU VECTRS+24 SELDSK EQU VECTRS+27 SETTRK EQU VECTRS+30 SETSEC EQU VECTRS+33 SETDMA EQU VECTRS+36 READ EQU VECTRS WRITR: CALL SETUP CALL WRITE RET NEXTR: CALL NXSEC ;BUMP TO NEXT SECTOR CC NXTRK ;BUMP TO NEXT CURTK JC ERR ;ERROR CALL READR RET PREVR: CALL PVSEC ;BUMP TO PREV. SECTOR CC PVTRK JC ERR CALL READR RET HDOUT: CALL PVTRK ;DE INX H DCR B JNZ BLANKIT RET ;**** ; READ ROUTINE ;**** READR: CALL SETUP CALL READ RET SETUP: LXI B,TBUF CALL SETDMA LDA CURDK MOV C,A CALL SELDSK LDA CURSC MOV C,A CALL SETSEC LDA CURTK MOV C,A CALL SETTRK RET ;MOV MSG1 TO SCREEN MVI A,00 ;CLEAR VDM I/O PORT OUT 0C8H STA CURDK ;SET DISK TO DRIVE 0 CALL HOME ;RESTORE HEAD XRA A STA CURTK ;SET CURTK BYTE INR A STA CURSC ;SET CURRENT SECTOR LXI H,VDMLC+128 LXI D,MSG2 MVI B,64 CALL MOVTG J RET MOVTG: LDAX D ORI 80H MOV M,A DCR B INX H INX D JNZ MOVTG RET HXO: MOV B,A ;SAVE BYTE IN B RRC RRC RRC RRC ;GET HI ORDER 4 BITS CALL HXN ;CONVERT TO HEX ASCII INX H ;BUMP MEM ADDRESS MOV A,B ;GET BYTE AGAIN CALL HSECTOR NUMBER LXI H,VDMLC+128+OF2 ;OFFSET TO FIELD2 LDA CURTK CALL HXO ;DISPLAY CURTK NUMBER LXI H,VDMLC+128+OF3 ;OFFSET TO FIELD3 LDA CURDK CALL HXO ;DISPLAY DISK NUMBER LXI H,VDMLC+128+OF4 CALL STAT CALL HXO LXI H,VDMLC+512 LXI D,TB+39 WRITE EQU VECTRS+42 GETVEC: LXI D,WBOOTE LHLD 1 MVI B,42 GETVE1: MOV A,M STAX D INX H INX D DCR B JNZ GETVE1 ; ;**** ; MAIN PROGRAM ;**** MAIN: LXI SP,STACK ;SET STACK LXI H,VDMLC ;POINT TO VDM MEMORY MVI B,4 ;4 PAGES IN CREMENT CURTK CALL READR ;READ SECTOR RET ;EXIT HDIN: CALL NXTRK ;INCREMENT CURTK CALL READR ;READ SECTOR RET ;MOVE HEAD NXSEC: LDA CURSC CPI 26 ;END OF CURTK JNC NXS2 ;YES INR A STA CURSC XRA A RET NXS2: MVI A,01 STA CURSC X H INX H DCR C ;ANY COMMANDS LEFT? JNZ CMLP ;YES, KEEP LOOKING ERR: LXI H,VDMLC+(15*64) MOV M,A INX H MVI M,'?' JMP LOOP CMOK: INX H MOV E,M INX H MOV D,M XCHG LXI D,LOOP PUSH D PCHL CONIN: CALL CI ANI 7FH CPI 3 JZ MP LOOP1 LOOP: CALL DSPLY ;DISPLAY PARAMETERS LOOP1: CALL CONIN ;READ CONSOLE LXI H,2020H ;CLEAR ERROR FLAG SHLD VDMLC+(15*64) LXI H,CMDTB ;POINT TO COMMAND TABLE MVI C,NCMDS ;NUMBER OF COMMANDS CMLP: CMP M ;COMMAND FOUND? JZ CMOK INX H IN RET HXI: LXI B,0 CALL HXC RC MOV B,A INX H CALL HXC CMC RNC MOV C,A MOV A,B ADD A ADD A ADD A ADD A ADD C MOV B,A MVI C,0 RET HXC: CALL CONIN MOV C,A CPI '0' RC CPI '9'+1 JNC HXA MOV M,A ANI 0FH RET ' DB ' ' MSG2: DB 'SECTOR ' MSG2A: DB 'TRACK ' MSG2B: DB 'DRIVE ' MSG2C: DB 'STATUS ' MSG2D: DB ' ' DB ' ' MSGI: DB ' BYTE # ' MSGILEN EQU $-MSGI OF1 EQU CALL GETEM XRA A ADD B JZ NWSEC CPI 1BH JNC NWSEC STA CURSC MOV A,C CPI 20H JZ NWTRK CALL READR RET GETBNO: LXI H,VDMLC+(14*64) LXI D,MSGI MVI B,MSGILEN CALL MOVTG CALL GETEM MOV A,B CPI 129 JNC GETBNO DCR A JM G!~/#DELETE? z_Y*w#-" DaD>2>-!"<:[f͹\U*}u|ʃ"nf:* 0 6)U$6)!* ~ $͌$kb))))_y¥$BK{͙$6)!6!?6!$""?80**{%#zTOR DW PREVR DB 'D' ;SELECT DISK DRIVE DW NWDSK DB 'D'+' ' DW NWDSK DB 'I' ;STEP HEAD IN DW HDIN DB 69H DW HDIN DB 'O' ;STEP HEAD OUT DW HDOUT DB 6FH DW HDOUT DB 'Q' ;QUIT (EXIT TO CP/M) DW 0 DB 'Q'+' ' DW 0 DB 'S' ;SPEC HXA: ANI 5FH CPI 'A' JC HXC CPI 'F'+1 JNC HXC MOV M,A SUI 37H ANI 0FH RET GETEM: MVI M,'?'+80H INX H MVI M,'?'+80H DCX H CALL HXI JNC GETEM1 LXI SP,STACK JMP LOOP GETEM1: MOV A,B DCX H CALL HXO RET NWDSK: LXI H,GET DISK STATUS ;********************************* STAT: IN 127 ;GET STATUS RET ;AND RETURN END URRENT SECTOR CURTK: DB 00 ;CURRENT TRACK CURDK: DB 00 ;CURRENT DISK BYTENO: DB 0 ;********************************* ; (MSG2A-MSG2)-3 OF2 EQU (MSG2B-MSG2)-3 OF3 EQU (MSG2C-MSG2)-3 OF4 EQU (MSG2D-MSG2)-3 DS 64 STACK EQU $ CURSC: DB 00 ;CURRENT SECTOR CURTK: DB 00 ;CURRENT TRACK CURDK: DB 00 ;CURRENT DISK BYTENO: DB 0 ;********************************* ; ETBNO STA BYTENO MVI B,MSGILEN+3 LXI H,VDMLC+(14*64) CALL BLANKIT RET HEXPAT: CALL GETBNO LDA BYTENO MOV C,A MVI B,0 LXI H,TBUF DAD B XCHG ADD A MOV C,A LXI H,VDMLC+512 DAD B HEXPA1: CALL GETEM MOV A,B STAX D INX D IFIC SECTOR DW NWSEC DB 'S'+' ' DW NWSEC DB 'T' DW NWTRK ;SPECIFIC TRACK DB 'T'+' ' DW NWTRK DB 'C' ;CLEAR ALL AND RESTART EXAM DW MAIN DB 'C'+' ' DW MAIN NCMDS EQU ($-CMDTB)/3 MSG1: DB ' EXAM VERSION 3.1 ' DB ' VDMLC+128+OF3 CALL GETEM MOV A,B CPI 2 JNC NWDSK STA CURDK CALL READR RET NWTRK: LXI H,VDMLC+128+OF2 CALL GETEM MOV A,B CPI 4DH JNC NWTRK STA CURTK MOV A,C CPI 20H JZ NWDSK CALL READR RET NWSEC: LXI H,VDMLC+128+OF1 !9"-1-L# x >2!,""?6,_N2[?????????????N2[ ڑ7/0/͆͆> /> /> /:[G_!~~2 #~9/#ͨ x̳~͗#ͨ:D LDA BYTENO INR A CPI 128 RNC STA BYTENO JMP ASCPA1 CMDTB: DB 'R' DW READR DB 'W' DW WRITR DB 'A' DW ASCPAT DB 'H' DW HEXPAT DB 72H DW READR DB '+' ;READ NEXT SECTOR DW NEXTR DB 0AH DW NEXTR DB '-' ;READ PREV SEC LDA BYTENO INR A CPI 128 RNC STA BYTENO JMP HEXPA1 ASCPAT: CALL GETBNO LDA BYTENO MOV C,A MVI B,0 LXI H,TBUF DAD B XCHG LXI H,VDMLC+256 DAD B ASCPA1: MVI M,'?'+80H CALL CONIN CPI 20H RC MOV M,A STAX D INX H INX ;***** ; OBTAIN BIOS VECTORS ;***** VECTRS: JMP GETVEC DS 42 WBOOTE EQU VECTRS+3 CSTS EQU VECTRS+6 CI EQU VECTRS+9 CO EQU VECTRS+12 LO EQU VECTRS+15 PO EQU VECTRS+18 RI EQU VECTRS+21 HOME EQU VECTRS+24 SELDSK EQU VECTRS+27 SETTRK EQU VECTRS+PCRL: PUSH PSW MOV A,L ; SEND CMA ; LOW BYTE OUT HTPD1 ; OF DATA ; MOV A,H ; SEND ANI 7 ; HIGH 3 MOV H,A ; BITS CMA ; OF OUT HTPD2 ; DATA ; POP PSW ; SET UP ANI 0F8H ; AND ORA H ; ACTIVATE CMA ; CONTROL OUT HTPD2 ; STROBE ; G IN MONITOR PATCH .LOC 0F812H ;LINE PRINTER VECTOR JMP HYTYPE ;AL=L ; .LOC HERE ;RELOCATABLE ; HYTYPE: PUSH H ; SAVE EVERYTHING PUSH D PUSH B PUSH PSW ; NOP ; MOV C,B FOR ALS8 ; MOV A,C ;TEST CHARACTER ANI 7FH CPI ' '+1 ; FOR CONRBIT ; BUZY? JNZ SPACE MVI A,CRSTB ; MOVE JMP HTPCRL ; CARRAGE ; LNFEED: ; IS IN HTPS ; PLATTEN ANI LFBIT ; BUZY? JNZ LNFEED MVI A,LFSTB ; ROLL JMP HTPCRL ; PLATTEN ; PRINT: ; IS IN HTPS ; PRINT WHEEL ANI PWBIT ; BUZY? JNZ PRIS WIDE WIDXX = WIDE/256*256 WIDHR = WIDE/256 ; RESET CARRAGE WIDLR = WIDE-WIDXX ; COUNTERS CSTEP = 60/CPINCH ; STEPS PER CHARACTER LMARGN = 60*2 ;LEFT HAND MARGIN ; ; INTERFACE PORTS HTPD1 = 06H ; FIRST DATA PORT HTPD2 = 07H ; SECOND DATA POR30 SETSEC EQU VECTRS+33 SETDMA EQU VECTRS+36 READ EQU VECTRS+39 WRITE EQU VECTRS+42 GETVEC: LXI D,WBOOTE LHLD 1 MVI B,42 GETVE1: MOV A,M STAX D INX H INX D DCR B JNZ GETVE1 ;  CALL DSPLCE MOV A,H ORA L CNZ SPACE ; TYPE1: MOV L,C ;TYPE CALL PRINT ; CHARACTER RET ; DSPLCE: MOV A,D ; ONE'S COMPLEMENT CMA ; DE MOV D,A MOV A,E CMA MOV E,A INX D ; TWO'S COMPLEMENT DE DAD D ; DE IS NOW -DE MOV A,H ; SETROL JM CNTRL CPI 7FH JZ HYTP1 ; CALL TYPE ; SO PRINT IT JMP STEP ; HYTP1: POP PSW ; RESTORE EVEYTHING POP B POP D POP H MOV A,C ;NOP FOR ALS-8 RET ; TYPE: LHLD CRPOS ; MOVE XCHG ; CARRAGE LHLD CRCNT ; IF SHLD CRPOS ; NEEDED.title 'Diablo Hytype I Printer Routine Z-80 VERSION' .sbttl 'Copyright 1976 by Technical Design Labs, inc.' ; VERSION 1.6 ; DIABLO HYTYPE I PRINTER ROUTINE ; ;COPYRIGHT 1976 BY TECHNICAL DESIGN LABS, INC. ; WRITTEN BY TOM KIRK ; ; NT MVI A,PWSTB ; SPIN JMP HTPCRL ; PRINT WHEEL ; CHECK: IN HTPS ; IS ANI CKBIT ; PRINTER RNZ ; OK? MVI A,RESTR ; RESTORE LXI H,0 ; PRINTER SHLD CRPOS ; TO LXI H,0 SHLD CRCNT ; LEFT CALL HTPCRL LXI H,LSTEP CALL LNFEED RET ; HTT HTPS = 06H ; STATUS PORT BS = 008H LF = 00AH CR = 00DH CRBIT = 004H LFBIT = 008H PWBIT = 001H CKBIT = 002H LFSTB = 008H CRSTB = 020H PWSTB = 010H RESTR = 080H ; RAM = 0 ;PLACE STORAGE ; AT OTHER THAN END OF PROGRAM HERE = 0fc00h ; ; PLUT SIGN BIT ORA A ; AS A RESULT RP MOV A,L ; BACKWARD CMA ; DISPLACEMENT INR A ; IS MOV L,A ; POSITIVE MOV A,H ; NUMBER CMA ; WITH ACI 0 ; SET ORI 0FCH ; SIGN MOV H,A ; BIT RET ; SPACE: CALL CHECK ; IS IN HTPS ; CARRAGE ANI CS ON TYPING AREA WIDTH = 132 ; WIDTH IN TENTHS OF AN INCH ; ; TYPE SIZE PARAMETERS LPINCH = 6 ; LINES PER INCH CPINCH = 10 ; CHARACTERS PER INCH ; ; CALCULATION OF PROGRAM CONSTANTS LSTEP = 48/LPINCH ; STEPS PER LINE ; WIDE = WIDTH*6 ; STEPSO LONG AS THE ORIGINATOR AND THE LIST ; OF MODIFIERS IS INSERTED INTO THE SOURCE ; CODE, AND KEPT INTACT, PERMISSION IS ; HEREBY GIVEN TO COPY, MODIFY, AND ; DISTRIBUTE FOR NON-COMMERCIAL PURPOSES. ; ; MODIFIED BY: ; ; DEC 22, 1976 ; ; LIMIT MOV A,H ; REMOVE CMA ; CONTROL OUT HTPD2 ; STROBE RET CNTRL: CPI ' ' ; MOVE DESIRED CARRAGE JNZ CNTR1 ; POSITION STEP: LXI D,CSTEP ; 1 CHARACTER LHLD CRCNT ; TO DAD D ; THE SHLD CRCNT ; RIGHT. MOV A,H ; RESET CARRAGE CPI WIDHR ; COUNSTA BHB LXI H,0 ; PRINTER SHLD CRPOS ; TO LXI H,LMARGN SHLD CRCNT ; LEFT CALL HTPCRL LXI H,LSTEP CALL LNFEED RET ; HTPCRL: PUSH PSW MOV A,L ; SEND CMA ; LOW BYTE OUT HTPD1 ; OF DATA ; MOV A,H ; SEND ANI 7 ; HIGH 3 MOV H,A ; = 080H ; RAM = 0 ;PLACE STORAGE ; AT OTHER THAN END OF PROGRAM HERE = . ; ; PLUG IN MONITOR PATCH .LOC 0F812H ;LINE PRINTER VECTOR JMP HYTYPE ;AL=L ; .LOC HERE ;RELOCATABLE ; HYTYPE: PUSH H ; SAVE EVERYTHING PUSH D PUSH B PUSH PSW LDXI D,-CSTEP DAD D ;CHARACTER SHLD CRCNT JMP HYTP1 ; .IFN RAM,[ ;LOCATION OF STORAGE .LOC RAM ;IF NON-ZERO] CRPOS: .WORD 0 ; SPACE POS NOW CRCNT: .WORD 0 ; SPACE POS FUTURE ; .end  WITH ACI 0 ; SET ORI 0FCH ; SIGN MOV H,A ; BIT RET ; SPACE: CALL CHECK ; IS IN HTPS ; CARRAGE ANI CRBIT ; BUZY? JNZ SPACE MVI A,CRSTB ; MOVE JMP HTPCRL ; CARRAGE ; LNFEED: ; IS IN HTPS ; PLATTEN ANI LFBIT ; BUZY? JNZ LNFEED ATION OF PROGRAM CONSTANTS LSTEP = 48/LPINCH ; STEPS PER LINE ; WIDE = WIDTH*6 ; STEPS WIDE WIDXX = WIDE/256*256 WIDHR = WIDE/256 ; RESET CARRAGE WIDLR = WIDE-WIDXX ; COUNTERS CSTEP = 60/CPINCH ; STEPS PER CHARACTER LMARGN = 60*2 ;LEFT HAND MTER AFTER JC HYTP1 ; RIGHT HAND LIMIT MOV A,L ; IS REACHED CPI WIDLR JC HYTP1 ; DON'T RUN INTO LXI H,LMARGN ;END STOP. SHLD CRCNT ; NEW LINE LXI H,LSTEP ; TOO. CALL LNFEED JMP HYTP1 ; CNTR1: CPI CR ; SET DESIRED JNZ CNTR2 ; CARRAGE MOV A,C ;NOP FOR ALS-8 RET ; TYPE: LHLD CRPOS ; MOVE XCHG ; CARRAGE LHLD CRCNT ; IF SHLD CRPOS ; NEEDED CALL DSPLCE MOV A,H ORA L CNZ SPACE ; TYPE1: MOV L,C ;TYPE CALL PRINT ; CHARACTER RET ; DSPLCE: MOV A,D ; ONE'S COMPLEMENT A BHB ORA A CZ FIRST ; NOP ; MOV C,B FOR ALS8 ; MOV A,C ;TEST CHARACTER ANI 7FH CPI ' '+1 ; FOR CONTROL JM CNTRL CPI 7FH JZ HYTP1 ; CALL TYPE ; SO PRINT IT JMP STEP ; HYTP1: POP PSW ; RESTORE EVEYTHING POP B POP D POP H .title 'Diablo Hytype I Printer Routine 8080 VERSION' .sbttl 'Copyright 1976 by Technical Design Labs, inc.' .I8080 ; 8080 version trap ; VERSION 2.0 (8080) ; DIABLO HYTYPE I PRINTER ROUTINE ; ;COPYRIGHT 1976 BY TECHNICAL DESIGN LABS, INC. MVI A,LFSTB ; ROLL JMP HTPCRL ; PLATTEN ; PRINT: ; IS IN HTPS ; PRINT WHEEL ANI PWBIT ; BUZY? JNZ PRINT MVI A,PWSTB ; SPIN JMP HTPCRL ; PRINT WHEEL ; CHECK: IN HTPS ; IS ANI CKBIT ; PRINTER RNZ ; OK? FIRST: MVI A,RESTR ; RESTORE ARGIN ; ; INTERFACE PORTS HTPD1 = 06H ; FIRST DATA PORT HTPD2 = 07H ; SECOND DATA PORT HTPS = 06H ; STATUS PORT BS = 008H LF = 00AH CR = 00DH CRBIT = 004H LFBIT = 008H PWBIT = 001H CKBIT = 002H LFSTB = 008H CRSTB = 020H PWSTB = 010H RESTR LXI H,LMARGN ;POSITION SHLD CRCNT ; TO JMP HYTP1 ; LEFT MARGIN. ; CNTR2: CPI LF ; MOVE DESIRED JNZ CNTR3 ; PLATTEN POSITION LXI H,LSTEP ; UP BY CALL LNFEED ; ONE LINE. JMP HYTP1 ; CNTR3: CPI BS ;BACK JNZ HYTP1 ;SPACE LHLD CRCNT ;ONE LCMA ; DE MOV D,A MOV A,E CMA MOV E,A INX D ; TWO'S COMPLEMENT DE DAD D ; DE IS NOW -DE MOV A,H ; SET SIGN BIT ORA A ; AS A RESULT RP MOV A,L ; BACKWARD CMA ; DISPLACEMENT INR A ; IS MOV L,A ; POSITIVE MOV A,H ; NUMBER CMA ; ; Gary W. Hvizdak (on the first day of SPRING!) ; ; MAR 20, 1977 ; ; LIMITS ON TYPING AREA WIDTH = 132 ; WIDTH IN TENTHS OF AN INCH ; ; TYPE SIZE PARAMETERS LPINCH = 6 ; LINES PER INCH CPINCH = 10 ; CHARACTERS PER INCH ; ; CALCUL ; WRITTEN BY TOM KIRK ; ; SO LONG AS THE ORIGINATOR AND THE LIST ; OF MODIFIERS IS INSERTED INTO THE SOURCE ; CODE, AND KEPT INTACT, PERMISSION IS ; HEREBY GIVEN TO COPY, MODIFY, AND ; DISTRIBUTE FOR NON-COMMERCIAL PURPOSES. ; ; MODIFIED BY:BITS CMA ; OF OUT HTPD2 ; DATA ; POP PSW ; SET UP ANI 0F8H ; AND ORA H ; ACTIVATE CMA ; CONTROL OUT HTPD2 ; STROBE ; MOV A,H ; REMOVE CMA ; CONTROL OUT HTPD2 ; STROBE RET CNTRL: CPI ' ' ; MOVE DESIRED CARRAGE JNZ CNTR1 ; POSITBCA CALL GDB ;GET DATA BLOCK JC DONE ;FINS LXI D,FBUF ;COPY FBUF TO TBUF LXI H,TBUF MVI B,128 CALL MOVE MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB MVI C,WRITE CALL CPM ;WRITE THE BLOCK ON CPM ORA A JNZ IOERR LHLD BCNT ;GET BK 1 CALL SDSK CALL HOME ;HOME DISK 1 LXI D,DIRLNK ;POINT TO DIR LINK BLOCK LINK LXI H,DBCA ;DIR BCA CALL GLB ;GET LINK BLOCK ICL0: LXI H,DBCA ;DIR BCA CALL GDB ;GET DIR BLOCK JC NOTF ;NO MORE DIR BLOCKS, ERR LXI H,DBUF ;DIR BUFFER N POSITION LXI H,LSTEP ; UP BY CALL LNFEED ; ONE LINE. JMP HYTP1 ; CNTR3: CPI BS ;BACK JNZ HYTP1 ;SPACE LHLD CRCNT ;ONE LXI D,-CSTEP DAD D ;CHARACTER SHLD CRCNT JMP HYTP1 ; .IFN RAM,[ ;LOCATION OF STORAGE .LOC RAM ;IF NON-ZERO] CRXI D,MSG2 MVI C,09 CALL CPM JMP EXIT EXIT: MVI C,0 CALL SDSK ;SET DISK 0 JMP BOOT ICL2: LHLD DENT ;GET DIR ENTRY ADDRESS LXI D,12 ;OFFSET TO COUNT DAD D MOV E,M INX H MOV D,M ;BLOCK COUNT IN DE XCHG SHLD BCNT ;SAVE BLOCK ION STEP: LXI D,CSTEP ; 1 CHARACTER LHLD CRCNT ; TO DAD D ; THE SHLD CRCNT ; RIGHT. MOV A,H ; RESET CARRAGE CPI WIDHR ; COUNTER AFTER JC HYTP1 ; RIGHT HAND LIMIT MOV A,L ; IS REACHED CPI WIDLR JC HYTP1 ; DON'T RUN INTO LXI H,LMARGN ;ENN MVI B,6 ;FN SIZE CALL FCHK ;TEST FN JNZ ILN1 ;NO, GET NEXT ENTRY LHLD DENT ;GET DIR ENTRY ADDR LXI D,7 ;OFFSET TO EXT. DAD D ;ADDR OF EXT. LXI D,TFCB+1+8 ;EXT MVI B,3 ;SIZE OF EXT. CALL FCHK ;TEST EXT JZ ICL2 ;OK, FOUND FILE SHLD DENT ;SAVE IN POINTER MVI A,8 ;NUMBER OF ENTRIES/BLOCK STA DCNT ;SAVE ICL1: LHLD DENT ;GET DIR ENTRY PTR MOV A,M ;GET STATUS BYTE CPI 00 ;ACTIVE? JNZ ILN1 ;NO, GET NEXT ENTRY INX H ;POINT TO FN LXI D,TFCB+1 ;POINT TO ENTERED FPOS: .WORD 0 ; SPACE POS NOW CRCNT: .WORD 0 ; SPACE POS FUTURE BHB: .BYTE 0 ; Been Here Before???? ; .end ONE LXI D,-CSTEP DAD D ;CHARACTER SHLD CRCNT JMP HYTP1 ; .IFN RAM,[ ;LOCATION OF STORAGE .LOC RAM ;IF NON-ZERO] CRCOUNT INX D ;POINT TO LINK BLOCK LINK LXI H,FBCA ;FILE BCA CALL GLB ;GET LINK BLOCK MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB ;POINT TO FCB MVI C,CREATE CALL CPM ;CREATE FILE CPI 0FFH ;ERROR? JZ IOERR ICL3: LXI H,FBCA ;POINT TO ;**************************************** ; ; ISIS II TO CPM ; FILE COPY UTILITY ; ; VERSION 1.0 ; ;**************************************** ORG 100H ICOPY: LXI SP,STACK ;SET STACK MVI C,1 ;SELECT DISD STOP. SHLD CRCNT ; NEW LINE LXI H,LSTEP ; TOO. CALL LNFEED JMP HYTP1 ; CNTR1: CPI CR ; SET DESIRED JNZ CNTR2 ; CARRAGE LXI H,LMARGN ;POSITION SHLD CRCNT ; TO JMP HYTP1 ; LEFT MARGIN. ; CNTR2: CPI LF ; MOVE DESIRED JNZ CNTR3 ; PLATTE ILN1: LHLD DENT ;POINTER TO ENTRY LXI D,16 ;SIZE OF ENTRY DAD D ;POINT TO NEXT ENTRY SHLD DENT LDA DCNT ;ENTRY COUNTER DCR A ;DECREMENT STA DCNT JNZ ICL1 ;LOOP JMP ICL0 NOTF: LXI D,MSG1 MVI C,09 CALL CPM JMP EXIT IOERR: LLOCK COUNT DCX H ;DECREMENT SHLD BCNT MOV A,H ORA L ;TEST FOR DONE JNZ ICL3 ;NO, LOOP DONE: MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB ;FCB MVI C,CLOSE CALL CPM JMP BOOT ;FINISHED ;***************************************; ; ; MSG1: DB 'FILE NOT FOUND',0DH,0AH,'$' MSG2: DB 'I/O ERROR',0DH,0AH,'$' DIRLNK: DB 01,01 DENT: DS 2 DCNT: DS 1 BCNT: DS 2 BCAP: DS 2 DS 64 STACK EQU $ DBCA: DS 2 DS 1 DS 128 DBUF: DS 128 FBCA: DS 2 DS 1 DS 128 FBUF: DS 128 TB END OK MOV A,M ;GET BYTE CPI ' ' ;END BOTH RZ ;DONE ORA 1 RET ;DONE FCK2: CMP M ;COMPARE RNZ ;N,G. INX D INX H DCR B ;DECREMENT COUNT JNZ FCK1 RET ;***************************************; ; ; SEEKR: SEEK DI,E INX H MOV M,D ;SET LINK PTR LHLD BCAP ;BCA ADDR LXI D,BCALC ;LINK COUNT DAD D MVI M,62 ;NO OF LINKS RET ;****************************************: ; ; GDB: GET DATA BLOCK ; ; HL= A(BLOCK CONTROL AREA) ; 1H ;GET BIOS ADDR MVI L,1BH PCHL SSEC: LHLD 0001H MVI L,21H PCHL STRK: LHLD 0001H MVI L,1EH PCHL READ: LHLD 0001H MVI L,27H PCHL HOME: LHLD 0001H MVI L,18H PCHL ;******************************************; ; ; BLOCK CONTROL ARV E,M ;GET LINK INX H MOV D,M DCX H MOV E,A ORA D ;TEST FOR ZERO LINK JZ GDBE ;END, EXIT XCHG ;DE = A(NEXT LINK) LHLD BCAP ;BCA ADDR CALL GLB ;GET LINK BLOCK RET GDBE: STC ;INDICATE EOF RET ;**************************** GLB - GET LINK BLOCK ; ; DE= A(LINK TO LINK BLOCK) ; HL= A(BLOCK CONTROL AREA) ; ;***************************************; GLB: SHLD BCAP ;SAVE BCA ADDR CALL SEEKR ;READ LINK BLOCK LHLD BCAP ;GET BCA ADDR LXI D,BCBLT TRACK MOV C,A CALL STRK CALL READ ;READ BLOCK POP D RET ;*****************************************; ; ; MOVE: MOVE DATA ; ; DE = A (SOURCE) ; HL = A(DEST) ; B = COUNT ; ;******************************************; MOVE: LSK BLOCK ; ; DE = A(LINK) ; ;***************************************; SEEKR: PUSH D ;SAVE DE MVI C,1 ;SET DISK B CALL SDSK POP D PUSH D LDAX D ;GET SECTOR MOV C,A CALL SSEC ;SET SECTOR POP D PUSH D INX D LDAX D ;GE ;****************************************; GDB: SHLD BCAP ;SAVE BCA ADDR LXI D,BCAL ;OFFSET TO LINK BUF DAD D MOV E,M INX H MOV D,M ;GET LINK ADDR PUSH D ;SAVE LINK ADDR LDAX D ;GET LINK BYTE INX D MOV C,A LDAX D ;GET ANOTHER EA DEFINITIONS ; ;******************************************; BCA EQU 0 BCAL EQU 0 BCALC EQU BCAL+2 BCBL EQU BCALC+1 BCBD EQU BCBL+128 ;******************************************; ; ; DATA ; ;******************************************;********; ; ; FCHK: FILE ID CHECK ; ; DE = A(ISIS FILE ID) ; HL = A(CPM FILE ID) ; B = SIZE OF FIELD ; ;*************************************; FCHK: XCHG FCK1: LDAX D ;GET BYTE CPI 00 ;SEE IF END OF ID JNZ FCK2 ;YES, SEE IF ;OFFSET TO LINK BUFFER DAD D LXI D,TBUF MVI B,128 CALL MOVE ;COPY TO LINK BUFFER LHLD BCAP ;GET BCA ADDR LXI D,BCBL+4 ;OFFSET TO FIRST DATA LINK XCHG DAD D ;DE=A(FIRST DATA LINK) XCHG LXI B,BCAL ;OFFSET TO LINK PTR DAD B MOV MDAX D ;GET BYTE MOV M,A ;STORE BYTE INX H INX D ;BUMP PTRS DCR B ;DECREMENT COUNT JNZ MOVE RET ;*******************************************; ; ; CPM INTERFACE ROUTINES ; ;*******************************************; SDSK: LHLD 000ET TO DATA BUF DAD D LXI D,TBUF MVI B,128 CALL MOVE ;COPY DATA TO BUF LHLD BCAP ;GET BCA ADDR LXI D,BCALC ;LINK COUNT DAD D DCR M ;DECREMENT RNZ ;OK, CONTINUE LHLD BCAP ;GET BCA ADDR LXI D,BCBL+2 ;POINT TO LINK BUF DAD D MOLINK BYTE ORA C ;TEST FOR ZERO LINK POP D JZ GDBE ;END, EXIT PUSH D ;SAVE D AGAIN PUSH H CALL SEEKR ;GET DATA BLOCK POP H POP D INX D INX D MOV M,D DCX H MOV M,E ;UPDATE LINK PRT LHLD BCAP ;GET BCA ADDR LXI D,BCBD ;OFFSUF EQU 0080H TFCB EQU 005CH CPM EQU 0005H BOOT EQU 0000H CREATE EQU 22 WRITE EQU 21 CLOSE EQU 16 END 2 BCAP: DS 2 DS 64 STACK EQU $ DBCA: DS 2 DS 1 DS 128 DBUF: DS 128 FBCA: DS 2 DS 1 DS 128 FBUF: DS 128 TBDE = A(NEXT LINK) LHLD BCAP ;BCA ADDR CALL GLB ;GET LINK BLOCK RET GDBE: STC ;INDICATE EOF RET ;***************************************; ; ; SEEKR: SEEK DISK BLOCK ; ; DE = A(LINK) ; ;********************************K CONTROL AREA) ; ;***************************************; GLB: SHLD BCAP ;SAVE BCA ADDR CALL SEEKR ;READ LINK BLOCK LHLD BCAP ;GET BCA ADDR LXI D,BCBL ;OFFSET TO LINK BUFFER DAD D LXI D,TBUF MVI B,128 CALL MOVE ;COPY TO LINK BUFFER EEKR ;GET DATA BLOCK POP H POP D INX D INX D MOV M,D DCX H MOV M,E ;UPDATE LINK PRT LHLD BCAP ;GET BCA ADDR LXI D,BCBD ;OFFSET TO DATA BUF DAD D LXI D,TBUF MVI B,128 CALL MOVE ;COPY DATA TO BUF LHLD BCAP ;GET BCA ADDR LXSG MVI C,09 CALL CPM ;PRINT 'B: ' MESSAGE POP H CALL FPRT ;PRINT FILE ID ILN1: LHLD DENT ;POINTER TO ENTRY LXI D,16 ;SIZE OF ENTRY DAD D ;POINT TO NEXT ENTRY SHLD DENT LDA DCNT ;ENTRY COUNTER DCR A ;DECREMENT STA DCNT JNZ ICL1D MVI M,62 ;NO OF LINKS RET ;****************************************: ; ; GDB: GET DATA BLOCK ; ; HL= A(BLOCK CONTROL AREA) ; ;****************************************; GDB: SHLD BCAP ;SAVE BCA ADDR LXI D,BCAL LHLD BCAP ;GET BCA ADDR LXI D,BCBL+4 ;OFFSET TO FIRST DATA LINK XCHG DAD D ;DE=A(FIRST DATA LINK) XCHG LXI B,BCAL ;OFFSET TO LINK PTR DAD B MOV M,E INX H MOV M,D ;SET LINK PTR LHLD BCAP ;BCA ADDR LXI D,BCALC ;LINK COUNT DAD ;**************************************** ; ; ISIS II TO CPM ; DIRECTORY UTILITY ; ; VERSION 1.0 ; ;**************************************** ORG 100H ICOPY: LXI SP,STACK ;SET STACK MVI C,1 ;SELECT DISI D,BCALC ;LINK COUNT DAD D DCR M ;DECREMENT RNZ ;OK, CONTINUE LHLD BCAP ;GET BCA ADDR LXI D,BCBL+2 ;POINT TO LINK BUF DAD D MOV E,M ;GET LINK INX H MOV D,M DCX H MOV E,A ORA D ;TEST FOR LINK JZ GDBE ;END, ERROR XCHG ; ;LOOP JMP ICL0 DONE: MVI C,0 CALL SDSK JMP BOOT IOERR: LXI D,MSG2 MVI C,09 CALL CPM JMP BOOT ;***************************************; ; ; GLB - GET LINK BLOCK ; ; DE= A(LINK TO LINK BLOCK) ; HL= A(BLOC;OFFSET TO LINK BUF DAD D MOV E,M INX H MOV D,M ;GET LINK ADDR PUSH D ;SAVE LINK ADDR LDAX D ;GET LINK BYTE MOV C,A INX D LDAX D ;GET LINK BYTE ORA C ;TEST FOR ZERO LINK POP D JZ GDBE ;ZERO LINK, EOF PUSH D PUSH H CALL SFER SHLD DENT ;SAVE IN POINTER MVI A,8 ;NUMBER OF ENTRIES/BLOCK STA DCNT ;SAVE ICL1: LHLD DENT ;GET DIR ENTRY PTR MOV A,M ;GET STATUS BYTE CPI 00 ;ACTIVE? JNZ ILN1 ;NO, GET NEXT ENTRY INX H ;POINT TO FN PUSH H ;SAVE HL LXI D,BMK 1 CALL SDSK CALL HOME ;HOME DISK 1 LXI D,DIRLNK ;POINT TO DIR LINK BLOCK LINK LXI H,DBCA ;DIR BCA CALL GLB ;GET LINK BLOCK ICL0: LXI H,DBCA ;DIR BCA CALL GDB ;GET DIR BLOCK JC DONE ;NO MORE DIR BLOCKS, FINISHED LXI H,DBUF ;DIR BUF*******; SEEKR: PUSH D ;SAVE DE MVI C,1 ;SET DISK B CALL SDSK POP D PUSH D LDAX D ;GET SECTOR MOV C,A CALL SSEC ;SET SECTOR POP D PUSH D INX D LDAX D ;GET TRACK MOV C,A CALL STRK CALL READ ;READ BLOCK POP D RET ;FILL FCB JMP FMAKE ;FILE CREATE JMP FOPEN ;FILE OPEN JMP FCLOS ;FILE CLOSE JMP FDELE ;DELETE FILE JMP OUTBT ;BYTE OUTPUT JMP GETBT ;BYTE INPUT ;********************************; ; F F C B ; ; ROUTINE TO FILL IN ID FIL CPM POP B POP H FPRT4: DCR B JNZ FPRT2 MVI C,02 MVI E,0DH CALL CPM MVI C,02 MVI E,0AH CALL CPM RET ;*****************************************; ; ; MOVE: MOVE DATA ; ; DE = A (SOURCE) ; HL = A(DEST) ; B = COUNT ; ;*** CPM EQU 0005H ;CPM ENTRY POINT TBUF EQU 0080H ;TRANS. BUFFER TFCB EQU 005CH ;TRANS. FCB SDISK EQU 14 ;SET DISK FUNCT. CODE OPEN EQU 15 ;OPEN FUNCTION CODE CLOSE EQU 16 ;CLOSE FUNCTION CODE DELET EQU 19 ;DELETE FUNCTION CODE READ EQU 20 ;READ FTA ; ;******************************************; BMSG: DB 'B: $' MSG2: DB 'I/O ERROR',0DH,0AH,'$' DIRLNK: DB 01,01 DENT: DS 2 DCNT: DS 1 BCNT: DS 2 BCAP: DS 2 DS 64 STACK EQU $ DBCA: DS 2 DS 1 DS 128 DBUF: DS 128 FBCA: DS 2 DS 1*****************************************; ; ; FPRT: PRINT FILE ID ; ; HL = A(FILE ID) ; ;*****************************************; FPRT: MVI B,9 ;ID SIZE FPRT2: MOV A,M ;GET BYTE CPI 00 ;IF ZERO,SKIP JNZ FPRT3 MVI A,' ' FPRT3: MOV E,A***************************************; MOVE: LDAX D ;GET BYTE MOV M,A ;STORE BYTE INX H INX D ;BUMP PTRS DCR B ;DECREMENT COUNT JNZ MOVE RET ;*******************************************; ; ; CPM INTERFACE ROUTINES ; ;***********UNCTION CODE WRITE EQU 21 ;WRITE FUNCTION CODE CREAT EQU 22 ;CREATE FUNCTION CODE RENAM EQU 23 ;RENAME FUNCTION CODE ;********************************; ; JUMP VECTORS ; ;********************************; ORG 1000H JMP FFCB ; DS 128 FBUF: DS 128 TBUF EQU 0080H TFCB EQU 005CH CPM EQU 0005H BOOT EQU 0000H CREATE EQU 22 WRITE EQU 21 CLOSE EQU 16 END  ;PUT IN E PUSH H ;SAVE HL PUSH B ;SAVE BC MVI C,02 ;WRITE CONSOLE CALL CPM ;PRINT CHAR POP B ;RESTORE BC POP H ;RESTORE HL INX H ;BUMP POINTER MOV A,B CPI 04 ;FILE TYPE? JNZ FPRT4 MVI E,' ' MVI C,02 PUSH H PUSH B CAL;********************************; ; LOGICAL I/O SYSTEM FOR CP/M ; ;********************************; ;********************************; ; MISCELLANEOUS EQUATES ; ;********************************; BOOT EQU 0000H ;REBOOT ENTRY POINT***************************; ; ; BLOCK CONTROL AREA DEFINITIONS ; ;******************************************; BCA EQU 0 BCAL EQU 0 BCALC EQU BCAL+2 BCBL EQU BCALC+1 BCBD EQU BCBL+128 ;******************************************; ; ; DA********************************; SDSK: LHLD 0001H ;GET BIOS ADDR MVI L,1BH PCHL SSEC: LHLD 0001H MVI L,21H PCHL STRK: LHLD 0001H MVI L,1EH PCHL READ: LHLD 0001H MVI L,27H PCHL HOME: LHLD 0001H MVI L,18H PCHL ;***************ELDS ; ; OF FCB ; ; ; ; INPUTS: HL = A(FCB) ; ; DE = A(ID STRING) ; ; OUTPUTS: CARRY = ERROR ; ;********************************; FFCB: MVI M,00 ;CLEAR FIRST *******************; GETBT: LXI H,IBUF+128 XCHG ;BUFFER END ADDR. IN DE LHLD INPTR ;CURRENT POINTER IN HL CALL CPHL ;TEST FOR END OF BUFFER JZ GETB2 ;YES, READ GETB1: MOV A,M ;GET BYTE INX H ;BUMP POINTER SHLD INPTR ;SAVE POINTER ORA A ;*****************************; FCLOS: MVI C,CLOSE ;CLOSE CODE CALL CPM CPI 0FFH ;ERROR? JZ FCERR ;YES XRA A ;CLEAR CARRY RET FCERR: STC RET ;********************************; ; F D E L E ; ; ROUTINE TO DELETE A DI PROCESS TYPE MOV M,A ;STORE NAME BYTE INX D INX H ;BUMP POINTERS DCR C ;DECREMENT MAX COUNT JNZ FFCB2 ;LOOP JMP FFCBE ;ERROR, NAME TOO BIG FFCB3: INX D ;SKIP OVER '.' FFCB4: INX H ;SKIP TO TYPE FIELD DCR C JNZ FFCB4 MVI C,3 ;SIZE OF F ;POINT TO OUTPUT BUFFER LXI H,TBUF ;TEMP BUFFER MVI B,128 CALL MOVE ;COPY BUFFERS MVI C,WRITE ;WRITE CODE LXI D,OFCB ;OUTPUT FCB CALL CPM ;ISSUE WRITE CPI 00 ;OK? JNZ OERR ;NO OUT2A: LXI H,OBUF ;RESET POINTER SHLD OUTPT JMP OUT1 ;CON FILE ; ; ; ; INPUT: DE=A(FCB) ; ; OUTPUT: CARRY=ERROR ; ;********************************; FOPEN: MVI C,OPEN ;OPNE CODE CALL CPM ;ISSUE OPEN CPI 0FFH ;ERROR? JZ FOERR ;YES XRA A ;CLEBYTE OF FCB INX H ;SKIP BYTE PUSH H ;SAVE FCB NAME ADDRESS MVI C,8+3 ;SIZE OF ID FIELD MVI A,' ' ;SPACE FFCB0: MOV M,A ;CLEAR ID FIELD TO SPACES INX H DCR C JNZ FFCB0 POP H ;GET ID FIELD ADDR. MVI C,8 ;MAZ SIZE OF NAME FFCB1: LDAX D ;GE ; ; ROUTINE TO OUTPUT A BYTE ; ; ; ; INPUT: A=BYTE) ; ; OUTPUT: CARRY=ERROR ; ;********************************; OUTBT: STA TEMP ;SAVE BYTE OUT1: LXI H,OBUF+128 XCHG ;BUFFESK FILE ; ; ; ; INPUT: DE=A(FCB) ; ;********************************; FDELE: MVI C,DELET CALL CPM ;ISSUE DELETE XRA A ;RESET CARRY RET ;********************************; ; O U T B T TYPE FIELD FFCB5: LDAX D ;GET ID BYTE CPI 0DH ;CR? RZ ;YES, DONE CPI ' ' ;SPACE? RZ ;YES, DONE MOV M,A ;STORE TYPE BYTE INX D ;BUMP POINTER INX H DCR C ;DECREMENT MAX COUNT JNZ FFCB5 ;LOOP RET ;DONE FFCBE: STC ;SET CARRY RET TINUE OERR: STC RET ;********************************; ; G E T B T ; ; ROUTINE TO READ A BYTE ; ; ; ; OUTPUTS: A=BYTE ; ; CARRY=ERROR ; ;*************AR CARRY RET FOERR: STC RET ;********************************; ; F C L O S ; ; ROUTINE TO CLOSE A DISK FILE ; ; ; ; INPUT: DE=A(FCB) ; ; OUTPUT: CARRY=ERROR ; ;***T ID BYTES CPI ' ' ;LEADING SPACES? JNZ FFCB2 ;NO, CONTINUE INX D ;SKIP LEADING SPACES JMP FFCB1 FFCB2: LDAX D ;GET ID BYTE CPI 0DH ;CR? RZ ;YES, DONE CPI ' ' ;IMBEDDED SPACE? RZ ;YES, DONE CPI '.' ;NAME.TYP SEPARATOR? JZ FFCB3 ;YES,R END ADDR IN DE LHLD OUTPT ;CURRENT ADDR IN HL CALL CPHL ;TEST FOR END OF BUFFER JZ OUT2 ;YES, WRITE LDA TEMP MOV M,A ;STORE DATA BYTE IN BUFFER INX H ;BUMP BUFFER POINTER SHLD OUTPT ;SAVE BUFFER POINTER ORA A RET ;EXIT OUT2: LXI D,OBUFMAKE: MVI C,CREAT ;CREATE CODE CALL CPM ;ISSUE CREATE CPI 0FFH ;ERROR? JZ FMERR ;YES XRA A ;CLEAR CARRY RET FMERR: STC ;SET CARRY RET ;EXIT ;********************************; ; F O P E N ; ; ROUTINE TO OPEN A DISK ;********************************; ; F M A K E ; ; ROUTINE TO CREATE A DISK FILE ; ; ; ; INPUT: DE=A(FCB) ; ; OUTPUT: CARRY=ERROR ; ;********************************; RESET CARRY RET GETB2: MVI C,READ ;READ CODE LXI D,IFCB ;FCB ADDRESS CALL CPM ;ISSUE READ CPI 00 ;ERROR? JNZ IERR ;YES LXI D,TBUF ;POINT TO TEMP BUFFER LXI H,IBUF ;INPUT BUFFER MVI B,128 CALL MOVE ;COPY BUFFER LXI H,IBUF ;RESET BUFFER 5 START: DI ;FIRST EXECUTABLE INSTR. LXI SP,STACK ; ; ; MAIN ; ==== ; LXI H,MSG1 ;WRITE ID AND REQUEST CALL MSG ; START ADDRESS MVI C,1 ;READ ONE 16-BIT VALUE CALL VALUE ; ONTO STACK LXI H,MSG2 CALL MSG ;REQUEST BEGIN,EWITH ; THE SAME BOOTSTRAP LOADER USED FOR EXTENDED (12K) BASIC. ; PROGRAMS ARE DUMPED DIRECTLY FROM MEMORY TO THE TAPE, AND ; PROVISION IS MADE FOR DUMPING NON-CONTIGUOUS BLOCKS OF ; MEMORY WITHOUT AFFECTING MEMORY IN-BETWEEN ON RELOAD. ; ; WHEN RUN, ; ; ROUTINE TO COMPARE HL VS DE ; ;********************************; CPHL: MOV A,H CMP D RNZ MOV A,L CMP E RET ;********************************; ; D A T A ; ;********************************; TEMP: DS 2 ;SOON AS ; SENSE SWITCH 15 IS MOVED FROM ITS PRESENT POSITION, ; SO START THE TAPE FIRST. LTG RETURNS TO CP/M WITH A REBOOT ; ON COMPLETION OF THE TAPE. LTG CAN BE RESTARTED FROM THE ; BEGINNING BY TYPING ESCAPE AT ANY TIME WHEN IT IS ACCEPTING ; INPUTPOINTER SHLD INPTR JMP GETB1 ;CONTINUE IERR: STC RET ;********************************; ; MISCELLANEOUS SUBROUTINES ; ;********************************; ;********************************; ; M O V E ; ; ROUTINE MISTAKE, CTRL-A WILL DELETE THE ENTIRE ; NUMBER. LTG THEN ASKS FOR BEGIN, END, AND LOAD ADDRESSES ; FOR EACH BLOCK. BEGIN AND END ARE THE ADDRESSES OF THE ; ACTUAL BEGINNING AND END OF THE PROGRAM IN MEMORY (NOW); ; LOAD SPECIFIES THE BEGINNING ADDRE LTG FIRST ASKS FOR "PROGRAM START ADDRESS"; THIS ; IS THE ADDRESS TO WHICH THE COMPUTER WILL JUMP AFTER LOADING ; THE TAPE (THE BEGIN EXECUTION ADDRESS OF THE PROGRAM). TYPE ; IN THE ADDRESS AS A HEXADECIMAL NUMBER, UP TO 4 HEX DIGITS. ; IF YOU MAKE ATEMP SAVE WORD IFCB: DS 33 ;INPUT FCB OFCB: DS 33 ;OUTPUT FCB OUTPT: DW OBUF ;OUTPUT POINTER INPTR: DW IBUF+128;INPUT POINTER OBUF: DS 128 ;INPUT BUFFER IBUF: DS 128 ;OUTPUT BUFFER END  FROM THE TERMINAL. ; ; ; HOUSEKEEPING ; ============ ; ;SMAX DEFINES MAX. NO OF SEPARATE MEMORY BLOCKS TO ;BE DUMPED. IF INCREASED, BE SURE TO ALSO INCREASE ;STACK LENGTH TO 8+5*SMAX (IN 'MESSAGES AND STORAGE') ; ; ORG 100H SMAX EQU ; AUDIO CASSETTE LOAD TAPE GENERATOR ; ; WRITTEN BY JEFFREY L. ZURKOW, ; CENTER FOR OUTRAGEOUS COMPUTATION, ; OCTOBER 6,1976. ; ; THIS PROGRAM CREATES SELF-LOADING AUDIO CASSETTE TAPES IN ; MITS CHECKSUM FORMAT. THE TAPES CREATED CAN BE LOADED TO MOVE BLOCKS OF DATA; ;********************************; MOVE: LDAX D ;GET BYTE MOV M,A ;STORE BYTE INX H INX D ;BUMPP POINTERS DCR B ;DECREMENT COUNT JNZ MOVE ;LOOP RET ;********************************; ; C P H L SS AT WHICH THE BLOCK ; IS TO BE LOADED WHEN THE TAPE IS PLAYED. THIS ALLOWS BLOCKS ; TO BE LOADED OFFSET IN MEMORY WHILE CREATING LOAD TAPES. ; TYPE CTRL-Z AFTER THE LAST BLOCK. THE MESSAGE "CHANGE ; SWITCH 15" WILL APPEAR- AUDIO OUTPUT WILL BEGIN AS ND,LOAD XRA A ;ZERO BLOCK COUNT, CLR CARRY STA SEGS ORA A ;CLEAR CARRY GET: MVI C,3 ;READ 3 WORDS CALL VALUE ; ONTO STACK POP B ;GET LOAD POP H ;GET END POP D ;GET BEGIN MOV A,L ;SUBTRACT DE SUB E ; FROM HL, SET MOV L,A ;JMP VALUE HEX: INR D ;INCR DIGIT CNTR MOV E,A ;SAVE DIGIT MOV A,D ;GET DIGIT CNTR CPI 5 JNC INP ;JMP IF CNTR>=5 DAD H ;SHIFT HL LEFT 4 DAD H DAD H DAD H MOV A,E ;GET DIGIT ANI 0FH ;MASK 4LSB ORA L ;MERGE,CLR CARRY MOV G3: DB 13,10,'FINISHED.',13,10,0 MSG4: DB 13,10,10,'CHANGE SWITCH 15',13,10,0 SEGS: DS 1 DS 38 ;THIS IS STACK LENGTH STACK: DS 1 ; ; ; VALUE ; ===== ; ;READS N 16-BIT HEX VALUES FROM TTY, WITH ECHO. ;VALUES MUST BE SEPARATED BY COMMA POP B ;GET PREVIOUS SW15 M3: IN 377Q ;GET PRESENT SW15 ANI 200Q XRA B ;TEST IF DIFFERENT JZ M3 MVI A,256Q ;WRITE LEADER MVI B,200 CALL LDR CALL CSL ;WRITE CHECKSUM LOADER MVI A,0 ;WRITE NULLS MVI B,100 CALL LDR ; ; DAT- CLR CARRY JMP INP DEL: MVI A,10 ;LINEFEED INR D ;ADJ FOR LOOP BSP: CALL TYOUT ;BACKSPACE TO VAL START MVI A,8 DCR D JNZ BSP XRA A ;CLR CARRY JMP VALUE FINAL: MOV A,B CPI 13 ;CAR RET? STC ;CLR CARRY CMC JNZ INP CCREMENT BLOCK COUNT DCR A STA SEGS JNZ DATA ;IF NOT 0,GET NEXT BLOCK MVI A,170Q ;WRITE GO BLOCK CALL TPUT POP H MOV A,L CALL TPUT MOV A,H CALL TPUT LXI H,MSG3 ;WRITE END MESG. CALL MSG XRA A JMP 0 ;REBOOT CP/M MSG1 CARRY IF NEG. MOV A,H SBB D MOV H,A JNC M1 ;JMP IF POS. LXI H,ERRM ;NEG; SEND CALL MSG ; MESG. JMP GET ;STACK CLEAN M1: PUSH D ;RESTORE BEGIN PUSH H ;RPLC END BY DIFF. PUSH B ;RESTORE LOAD MVI A,'?' CALL TYOUT LDN THE STACK AS THEY ARE ;READ, AFTER FIRST REMOVING THE RETURN ADDRESS. ;ON ENTRY, C MUST CONTAIN THE NO. OF VALUES TO ;BE READ, AND IF CARRY IS SET, THEN THE FIRST ;CHAR. IS ASSUMED TO BE ALREADY IN ACCUMULATOR. ; VALUE: LXI H,0 ;CLR VAL MOS AND NTH ;VALUE MUST BE FOLLOWED BY CAR. RET. ILLEGAL ;CHARACTERS ARE IGNORED, AS ARE ANY HEX ;DIGITS BEYOND THE 4TH IN A VALUE. CTRL A WILL ;CLEAR THE CURRENT VALUE, LINEFEED, ;AND BACKSPACE TO 1ST DIGIT TO BE RE-ENTERED. ;VALUES ARE PUSHED OA (OPEN SUBROUTINE) ; ====================== ; WRITES A BLOCK OF MEMORY ON TAPE IN CHECKSUM ; FORMAT BY REMOVING SUCCESSIVE CHUNKS OF 256 ; BYTES OR LESS, AND CALLING BLOCK. ; ON ENTRY, STACK CONTAINS: LOAD ADDR (TOP) ; BLOCK LNGTH - 1 ;ALL TYOUT ;ECHO CR MVI A,10 ;LF CALL TYOUT XTHL ;SAVE LAST VAL PCHL ;RETURN SAVE: ORA A ;CLR CARRY MOV E,C ;LAST VAL? DCR E JZ INP CALL TYOUT ;ECHO COMMA XTHL ;SAVE VAL PUSH H ;RESTORE RET ADDR DCR C ;DECR VAL CNTR : DB 13,10,10,10,10,'LOAD TAPE GENERATOR, VERSION 1.0',10 DB 13,10 DB 'PROGRAM START ADDRESS(HEX)',13,10,'?',0 MSG2: DB 13,10,'ENTER BEGIN,END,LOAD ADDRESS FOR EACH BLOCK' DB 13,10,'?',0 ERRM: DB 13,10,'END < BEGIN; TRY AGAIN',13,10,'?',0 MSA SEGS ;INCR. BLOCK COUNT INR A STA SEGS CPI SMAX JNC M2 ;JMP IF SEGS.GE.SMAX CALL TYIN CPI 26 ;TEST FOR CONTROL Z STC JNZ GET ;JMP IF NOT CTRL Z M2: IN 377Q ;READ SW15 ANI 200Q PUSH PSW ;SAVE IT LXI H,MSG4 CALL MSG V D,H ;CLR DIGIT CNTR INP: CNC TYIN ;READ CHAR IF NO CARRY CPI 1 ;CTRL-A? JZ DEL CPI 27 ;TEST FOR ESCAPE JZ START CPI ',' JZ SAVE CALL HEXA JNC HEX DCR C ;LAST VAL? JZ FINAL INR C ;RESTORE VAL CNTR XRA A ;NOT HEX, ILLEG.AN DCR D ;SUBTRACT 256 FROM LNGTH-1 PUSH D ;PUT BACK ON STK MVI E,255 ;OUTPUT 256 BYTES TO ACR CALL BLOCK JMP D1 LAST: CALL BLOCK ;OUTPUT LAST BLOCK ; ; (DATA ENDS) ; IN 0 RRC JC M4 IN 1 CPI 27 JZ START M4: LDA SEGS ;DE START ADDR ; ON RETURN, THESE HAVE BEEN REMOVED. ; ; DATA: POP B ;GET LOAD POP H ;GET LNGTH-1 XTHL ;GET BEGIN,PUT BACK LNGTH-1 D1: POP D ;GET LNGTH-1 MOV A,D ;TEST FOR LNGTH-1>255 ORA A JZ LAST ;IF NOT JMP TO LAST- STACK CLEL,A MOV A,B ;GET CHAR CALL TYOUT JMP INP ; ; ; HEXA ; ==== ; ;CHECKS IF CHAR. IS HEX, SETS CARRY IF NOT. ;CALL WITH CHAR. IN A; ON RETURN, A CONTAINS ;HEX DIGIT VALUE, B CONTAINS CHARACTER. ;FLAGS MODIFIED, C,D,E,H,L INTACT. ; A,M ORA A INX H OUT 1 JNZ MSG RET ; ; ; CSL ; === ; ;OUTPUTS CHECKSUM LOADER TO TAPE. ;PRESENT LOADER IS FROM 12K BASIC AND GOES ;INTO BLOCK 057Q. ITS LENGTH IS 256Q BYTES. ; CSL: LXI H,CLDE MVI B,256Q CSL1: MOV A,M E ;CALC. NO OF BYTES MOV A,E ; AND SEND TO TAPE CALL TPUT MOV D,C ;START CHECKSUM IN D MOV A,C ;LOW BYTE OF LOAD ADDR. CALL TPUT MOV A,B ;HIGH BYTE OF LOAD ADDR. CALL TPUT ADD D ;ADD HIGH BYTE TO CHECK MOV D,A MOVE: MOV A,M ;A57Q,76Q,103Q,1,76Q,115Q DB 1,76Q,117Q,323Q,1 DB 323Q,21Q,323Q,23Q,303Q,216Q,57Q,315Q,240Q,57Q,157Q,315Q DB 240Q,57Q,147Q,311Q,333Q,0,346Q,1,302Q,240Q,57Q,333Q DB 1,127Q,200Q,107Q,172Q CLDE: DB 311Q ; ; ====== ; ENDETH ; ====== END ; TPUT ; ==== ; ;OUTPUTS A BYTE FROM ACCUM. TO AUDIO CASSETTE. ;REQUIRES 2 BYTES OF STACK IN ADDITION TO RETURN ;ADDRESS; DOESN'T CHANGE REG'S OR FLAGS. ; TPUT: PUSH PSW TP1: IN 6 RLC JC TP1 POP PSW OUT 7 RET ; ; ; MSG HEXA: MOV B,A SUI 30H RC ADI 0E9H RC ADI 6 JP N10 ADI 7 RC N10: ADI 0AH ORA A RET ; ; ; BLOCK ; ===== ; ;WRITES ONE COMPLETE CHECKSUM DATA BLOCK ON ;AUDIO CASSETTE. ;ON CALL, BC CONTAINS LOAD ADDR ; HL 332Q,60Q,57Q,27Q,55Q,332Q,74Q,57Q,6,0,332Q DB 6,6,41Q,1,302Q,303Q,74Q,57Q,56Q,100Q,257Q DB 323Q,22Q,57Q,323Q DB 23Q,76Q,4,323Q,22Q,170Q,42Q,243Q,57Q,62Q,241Q DB 57Q,74Q,62Q DB 250Q,57Q,315Q,240Q,57Q,376Q,74Q,312Q,130Q,57Q,376Q,170Q DB 302 CALL TPUT DCX H DCR B JNZ CSL1 RET ; ;NOW FOLLOWS THE CHECKSUM LOADER ITSELF, IN AWFUL FORM. ; DB 363Q,61Q,262Q,57Q,333Q,377Q,46Q,312Q,6,0,27Q DB 332Q,50Q,57Q DB 27Q,56Q,40Q,332Q,74Q,57Q,27Q,56Q,2,332Q,74Q,57Q,6 DB 20Q,27Q,DD BYTE TO CHECKSUM CALL TPUT ;SEND TO TAPE ADD D ;ADD TO CHECKSUM MOV D,A INX H ;INCR. MEM ADDR. INX B ;INCR LOAD ADDR DCR E ;DECR COUNT JNZ MOVE ;CONTINUE IF >0 MOV A,D ;GET CHECKSUM CALL TPUT ;SEND TO TAPE RET ; ; ; ; ;================================================== Q,311Q,333Q,0,346Q,1,302Q,240Q,57Q,333Q DB 1,127Q,200Q,107Q,172Q CLDE: DB 311Q ; ; ====== ; ENDETH ; ====== END ; === ; ;PRINTS A MESSAGE ON THE TTY. ALSO CAUSES CHINESE ;RESTAURANT SYNDROME. ;ON ENTRY, HL CONTAINS POINTER TO MESSAGE STRING. ;A ZERO BYTE TERMINATES MESSAGE. ;MSG CHANGES A,F,HL, AND CHROMOSOMES. ; MSG: IN 0 RLC JC MSG MOV '' BEGIN ADDR ; E '' ONE LESS THAN BYTE COUNT ;ON RETURN, BC CONTAINS LOAD ADDR+BYTE COUNT ; A,D '' CHECKSUM ; E '' ZERO ; HL '' BEGIN ADDR+BYTE COUNT ; BLOCK: MVI A,74Q ;WRITE BLOCK HEADER CALL TPUT INRQ,107Q,57Q,315Q,227Q,57Q,351Q,315Q,240Q,57Q,117Q,6 DB 0,315Q,227Q,57Q,315Q,240Q,57Q,345Q,21Q,0,321Q,31Q DB 322Q,163Q,57Q,21Q,116Q,377Q,31Q,322Q,214Q,57Q,341Q,167Q DB 276Q,302Q,211Q,57Q,43Q,15Q,302Q,141Q,57Q,110Q,315Q,240Q DB 57Q,271Q,312Q,107Q,MOMENTARILY. ;LEAVES REGS, FLAGS INTACT. ; TYOUT: PUSH PSW TY1: IN 0 RLC JC TY1 POP PSW OUT 1 RET ; ; ; TYIN ; ==== ; ;READ A CHAR. FROM TTY AND LEAVE IN ACCUM. ; TYIN: IN 0 RRC JC TYIN IN 1 RET ; ; LDR ; === ; ;WRITES A BLOCK OF SOME CHARACTER ON ACR. ;CALL WITH CHAR. IN A, NUMBER OF REPETITIONS ;IN B. ; LDR: CALL TPUT DCR B JNZ LDR RET ; ; ; TYOUT ; ===== ; ;OUTPUTS CHAR. FROM ACCUM TO TTY. ;USES TWO STACK BYTES ;***************************; ; MAZE PROGRAM FROM INTEL ; ;***************************; ORG 100H CPM EQU 0005H BOOT EQU 0000H CR EQU 0DH LF EQU 0AH NUL EQU 0FFH FF EQU 0CH MAZE: LXI SP,STACK LXI D,MAZ MVI C,09 CALL CPM MAZE1: LXI D,CRCPI '9'+1 JNC BIN1 MOV C,A MOV A,C ANI 0FH MOV C,A MOV A,B ADD A MOV B,A ADD A ADD A ADD B ADD C MOV B,A JMP BIN1 BIN2: MOV A,B POP B RET RNDR: PUSH B CALL RND MOV C,A MVI B,0 RNDR1: DCR E JZ RNDR2 ADD C JNCELEFT: DCR C CALL MATRIX MOV A,M ORI 03H MOV M,A RET MOVERIGHT: CALL MATRIX MOV A,M ORI 02H MOV M,A INR C CALL MATRIX MOV A,M ORI 01H MOV M,A RET SCAN: INR C LDA CMAX CMP C JZ S1 S2: CALL MATRIX MOV A,M RRC C,09 CALL CPM SIZE1: CALL RND MVI C,11 CALL CPM ORA A JZ SIZE1 CALL BIN PUSH PSW LXI D,CRLF MVI C,9 CALL CPM POP PSW CPI 40+1 JNC SIZE STA CMAX SIZE2: LXI D,HIGH MVI C,09 CALL CPM CALL BIN PUSH PSW LXI D,CRLF MVI LXI D,CRLF MVI C,09 CALL CPM LXI D,OD MVI C,09 CALL CPM POP B MVI C,0 PM8: CALL MATRIX MOV A,M ANI 04H JZ PM9 PUSH B LXI D,OD MVI C,09 CALL CPM POP B JMP PM10 PM9: PUSH B LXI D,CD MVI C,09 CALL CPM POP B PM10: IN JNZ T6 RET MOVE: MVI A,1 STA MFLAG CALL RNDR MOV E,A MOV A,D INR E DCR E RRC JNC MV1 JZ MOVEUP DCR E MV1: RRC JNC MV2 JZ MOVEDOWN DCR E MV2: RRC JNC MOVERIGHT JZ MOVELEFT JMP MOVERIGHT MOVEUP: DCR B CALL MATRIX LF MVI C,09 CALL CPM MVI A,0 STA PFLAG STA MFLAG LXI H,MTX LXI B,MTXE M3: MVI M,0 INX H MOV A,L CMP C JNZ M3 MOV A,H CMP B JNZ M3 CALL SIZE LXI D,PAGE MVI C,09 CALL CPM CALL START M1: CALL TEST MOV A,E ORA A JZ MVI C,0 PM1: LDA SPOS CMP C JZ PM2 PUSH B LXI D,CD MVI C,09 CALL CPM POP B JMP PM3 PM2: PUSH B LXI D,OD MVI C,09 CALL CPM POP B PM3: INR C LDA CMAX CMP C JNZ PM1 PM4: PUSH B LXI D,CRLF MVI C,09 CALL CPM LXI D,CL JNC SCAN RET S1: MVI C,0 INR B LDA BMAX CMP B JNZ S2 MVI B,0 LDA MFLAG ORA A RZ MVI A,0 STA MFLAG JMP S2 PMAZE: LXI D,CRLF MVI C,09 CALL CPM LXI D,CRLF MVI C,09 CALL CPM LXI D,OD MVI C,09 CALL CPM MVI B,0 C,09 CALL CPM POP PSW CPI 40+1 JNC SIZE2 STA BMAX RET START: LDA CMAX MOV E,A CALL RNDR STA SPOS MOV C,A MVI B,0 CALL MATRIX MVI M,1 RET TEST: MVI D,0 MOV A,B CPI 0 JZ T1 DCR B CALL MATRIX INR B MOV A,M RRCR C LDA CMAX CMP C JNZ PM8 INR B LDA BMAX CMP B JNZ PM4 LXI D,CRLF MVI C,09 CALL CPM LXI D,PAGE MVI C,09 CALL CPM RET BIN: PUSH B MVI B,0 BIN1: PUSH B MVI C,01 CALL CPM POP B CPI CR JZ BIN2 CPI '0' JC BIN1 MOV A,M ORI 05H MOV M,A RET MOVEDOWN: CALL MATRIX MOV A,M ORI 04H MOV M,A LDA BMAX DCR A CMP B JZ MD1 INR B CALL MATRIX MOV A,M ORI 01H MOV M,A RET MD1: MVI A,1 STA PFLAG MVI B,0 LDA SPOS MOV C,A RET MOV M2 CALL MOVE JMP M1 M2: CALL SCAN JC M1 CALL PMAZE LXI D,AGAIN MVI C,09 CALL CPM MVI C,01 CALL CPM PUSH PSW MVI C,09 LXI D,CRLF CALL CPM POP PSW CPI 'Y' JZ MAZE1 CPI 079H JZ MAZE1 JMP BOOT SIZE: LXI D,WIDE MVIR MVI C,09 CALL CPM POP B MVI C,0 PM5: CALL MATRIX MOV A,M ANI 02H JZ PM6 PUSH B LXI D,OPR MVI C,09 CALL CPM POP B JMP PM7 PM6: PUSH B LXI D,CLR MVI C,09 CALL CPM POP B PM7: INR C LDA CMAX CMP C JNZ PM5 PUSH B IX INR C MOV A,M RRC JC T4 MOV A,D ORI 04H MOV D,A T4: LDA CMAX DCR A CMP C JZ T5 INR C CALL MATRIX DCR C MOV A,M RRC JC T5 MOV A,D ORI 08H MOV D,A T5: MVI E,0 MOV A,D ORA A T6: RAR