; MICRO-DECISION ; CP/M FORMAT PROGRAM VER. 2.4 ; COPYRIGHT 1982,1983,1984 ; MORROW DESIGNS, INC. ; 06/19/84 ; .Z80 ASEG ; ORG 100H ; RAMDATX EQU 2000H TRKBUF EQU RAMDATX+100H ; FMTCMD EQU 4DH ; SYS EQU 5 PBUFF EQU 9 RDCON EQU 6 IBUF EQU 80H ; WBOOT EQU 1 DISCIO EQU 39H RDBLK EQU 33H SECOFF EQU 1EH SELOFF EQU 18H HMOFF EQU 15H TRKOFF EQU 1BH DMAOFF EQU 21H WROFF EQU 27H MTOFF EQU 41H ; BTERR EQU 18H WRIO EQU 15H MESG EQU 3 ; LF EQU 0AH CR EQU 0DH ASCA EQU 41H ASC0 EQU 30H SPACE EQU 20H CTLC EQU 3 ; LTRK EQU 6 SIZMSK EQU 18H DSD EQU 5 DSM EQU 2 ; START: XOR A LD (EFLAG),A LD (IFLAG),A ; LD DE,MESG1 ;SIGN ON MESSAGE CALL PRNT ;CALL PRINT ROUTINE ; LD HL,IBUF ;SEE IF INPUT LINE LD A,(HL) OR A ;SEE IF ANY INPUT LINE JR Z,DAGN ;JMP IF NO INPUT ; LD B,A ILOP: INC HL LD A,(HL) CP SPACE JR NZ,INFD ; DJNZ ILOP ; XOR A LD (IBUF),A JR DAGN ; INFD: LD (IPNT),HL ;SAVE INPUT BUFFER DATA LD C,A DEC B LD A,B LD (ICNT),A LD A,C ; AND 0DFH CP 0AH JR NZ,SKCIN ; LD A,0FFH LD (IFLAG),A JR ILOP ; DAGN: LD DE,GDRV CALL PRNT DAGN1: CALL CIN SKCIN: LD (DRVM),A ;SAVE DRIVE IN MESSAGE LD (DRVT),A SUB 41È ;CONVERÔ TÏ ASCII JR C,BDRV ;JMP IF NOT VALID CP 5 ;CHECK UPPER BOUND JR C,DROK ;JMP IF VALID ; BDRV: LD DE,BKSP CALL PRNT JR DAGN1 ; DROK: PUSH AF ;SAVE DRIVE ; LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,MTOFF ;OFFSET TO MTAB POINTER ADD HL,DE ;HL = ADDRESS OF MATB POINTER ; LD E,(HL) ;SET DE = MTAB POINTER INC HL LD D,(HL) ; EX DE,HL ;HL = MTAB POINTER LD E,A ;E=DRIVE ; RLCA ;A = (2 X DRIVE) RLCA ;A = (4 X DRIVE) RLCA ;A = (8 X DRIVE) ADD A,E ;A = (9 X DRIVE) ; LD E,A ;DE = (9 X DRIVE) LD D,0 ; ADD HL,DE INC HL ;HL POINTS TO DSKDEF1 FOR THIS DRIVE ; LD A,3 ;MASK FOR PHYSICAL DRIVE ADDRESS AND (HL) ;MASK OUT PHYSICAL DRIVE ADDRESS ; LD (HDDRV),A ;PUT IN COMMAND BUFFER ; POP AF PUSH AF ; DEC HL ;GET DSKDEF0 POINTER ; BIT DSD,(HL) ;SEE IF DOUBLE SIDED DRIVE ; INC HL ;GET DSKDEF1 RES DSM,(HL) ;SET TO SINGLE SIDED MEDIA LD DE,DPBS LD (DPBP),DE ; LD DE,SNMSG ;SET MESSAGE POINTER LD (MSGP),DE ; LD DE,VTMSG LD (VTMSGP),DE ; JR Z,SSIDE ;JMP IF SINGLE SIDED DRIVE ; LD DE,VTMSGD LD (VTMSGP),DE ; PUSH HL ;SAVE POINTER ; LD A,(ICNT) ;SEE IF SIDE IS IN INPUT BUFFER OR A JR Z,SAGNP ;JMP IF NOT ; LD HL,(IPNT) LD B,A ; ILOPS: INC HL LD A,(HL) CP CR JR Z,SAGNP ; CP SPACE JR NZ,SIN ; DJNZ ILOPS ; SAGNP: LD DE,SDMSG ;# OF SIDES MESSAGE CALL PRNT POP HL ; SAGN: PUSH HL CALL CIN ;GET RESPONSE SIN: POP HL ;RESTORE DSKDEF1 POINTER AND 0DFH CP 'S' ;SEE IF SINGLE SIDE JR Z,SSIDE ;JMP IF SINGLE SIDE ; CP 'D' ;SEE IF DOUBLE SIDE JR Z,DSIDE ;JMP IF DOUBLE SIDE ; CP CR ;SEE IF CR JR NZ,INVAL ;JMP IF INVALID ; LD DE,DM ;PRINT DEFAULT PUSH HL CALL PRNT POP HL JR DSIDE ; INVAL: LD DE,BKSP ;CLEAR INVALID RESPONSE PUSH HL CALL PRNT JR SAGNP ;GO GET ANOTHER RESPONSE ; DSIDE: SET DSM,(HL) ;SET TO DOUBLE SIDED MEDIA LD DE,DPBD LD (DPBP),DE ; LD DE,DBMSG ;SET MESSEGE POINTER LD (MSGP),DE ; SSIDE: POP AF PUSH HL PUSH AF ; LD B,A LD A,(8) OR A JR NZ,NOT_ONE LD DE,VTMSG1 LD (VTMSGP),DE ; NOT_ONE:CP B JR NC,NVIRT ; LD HL,(1) LD DE,3FH ADD HL,DE LD E,(HL) INC HL LD D,(HL) LD HL,13H ADD HL,DE LD (HL),B LD (HLTMP),HL LD A,'A' LD (DRVM),A LD DE,IMSG1 LD A,(IFLAG) OR A JR NZ,VIRT LD DE,(VTMSGP) CALL PRNT LD DE,DRVT CALL PRNT LD DE,VT1 JR VIRT ; NVIRT: LD A,(IBUF) OR A JR NZ,EOK ; LD DE,MESG2 ;INSERT DISC MESG. VIRT: CALL PRNT ;PRINT MESG. EAGN: CALL CIN CP CR JR Z,EOK ; LD DE,BKSP CALL PRNT JR EAGN ; EOK: LD DE,CRLF CALL PRNT ; ; POP AF ;A=DRIVE LD (HSTDSK),A LD (VDSK),A LD C,A ;C=DRIVE CALL SELDSK ;SELECT DRIVE ; PUSH HL ;CALCULATE THE DPB ADDRESS POP IX ;FOR THIS DRIVE, AND PUT IT LD L,(IX+0AH) ;IN IX. LD H,(IX+0BH) PUSH HL POP IX ; ; AT THIS POINT WE HAVE A POINTER TO DSKDEF1 ON THE ; STACK, AND A POINTER TO DPB IN IX. THIS IS ALL THE ; INFORMATION THAT WE NEED TO DETERMINE WHAT FORMAT ; TO USE. ; POP HL ;GET DSKDEF1 POINTER LD B,(HL) ;B=DSKDEF1 ; PUSH IX ;SAVE DPB POINTER POP HL PUSH HL PUSH BC ;SAVE BC LD A,(HL) LD HL,FTAB256 ;POINTER TO FORMAT TABLE LD DE,M256 ; LD A,32 ;256 BYTES/SECTOR CP (IX+0) ;SEE IF DPB MATCHES JR NZ,NOT32 ; LD A,SIZMSK ;CHECK SECTOR SIZE AND B ;MASK SIZE CODE FROM DSKDEF1 CP 8 ;SEE IF 256 BYTES/SECTOR JR Z,FOK ;JMP IF 256 ; LD HL,FTAB512 LD DE,M512 JR FOK ; NOT32: LD HL,FTAB1K ;HL = POINTER TO FORMAT TABLE LD DE,DMSG ; LD A,40 ;1K TRACKS/SECTOR CP (IX+0) ;SEE IF DPB MATCHES JR FOK ;DO STANDARD 1K FORMAT UNLESS OTHER ;FORMAT IS RECOGNIZED. ; LD DE,IDSK JP ERROR ; FOK: BIT DSM,B ;SEE IF DS MEDIA JR Z,SSD0 ;JMP IF SS PUSH DE LD DE,7 ADD HL,DE POP DE ; SSD0: PUSH HL POP IX CALL PRNT LD DE,(MSGP) CALL PRNT ; PUSH IX ;XFER PARAMS. FROM FTAB TO COMD. BUF. POP HL INC HL INC HL LD DE,FDCCMD+2 LD BC,4 LDIR ; DOK: CALL HOME ;HOME DRIVE ; ; LD DE,FMSGI CALL PRNT ; XOR A ;A=0 ; FORML: LD (HSTTRK),A ;SET TRACK ; POP BC ;B=DSKDEF1 PUSH BC ;SAVE DSKDEF1 PUSH AF ; BIT DSM,B ;SEE IF DS MEDIA ; SCF ;CLEAR CY CCF ; JR Z,SSD1 ;JMP IF SS ; RRA ;SET A & CY FOR DS ; SSD1: LD (PHYTRK),A ; LD A,0 RLA RLA RLA LD (PHYHD),A ; POP AF CALL ASCII ;CONVERT TO ASCII LD (MTRK),BC ;PUT IN MESG. ; LD DE,FORMSG ;FORMATING MESG. CALL PRNT ; LD A,(HDDRV) RES 2,A LD B,A LD A,(PHYHD) OR B LD (HDDRV),A ; LD E,(IX+0) ;DE = PNTR. TO SECTOR TABLE LD D,(IX+1) ; LD HL,TRKBUF ; BLDL: LD A,(PHYTRK) ;A=TRACK LD (HL),A ;SET CYLINDER INC HL ; LD A,(PHYHD) ;A=HEAD RRCA RRCA LD (HL),A ;SET HEAD INC HL ; LD A,(DE) ;A=SECTOR LD (HL),A ;SET RECORD INC DE ;INC SECTOR TABLE POINTER INC HL ; LD A,(IX+2) ;A=N=SIZE BYTE FOR HEADER LD (HL),A ;SET N INC HL ; LD A,(DE) ;A=NEXT SECTOR CP 0FFH ;IS IT THE END JP NZ,BLDL ;JMP IF NOT END ; CALL WRTT ;WRITE TRACK ; OR A JP NZ,WERROR ;JMP IF ERROR ; LD A,(HSTTRK) ;A=TRACK INC A ;INC TRACK CP (IX+LTRK) ;LAST TRACK? JP NZ,FORML ;JMP IF NOT DONE ; ; FDONE: LD DE,VMSGI CALL PRNT ; LD L,(IX+0) ;HL=SECTOR TABLE ADDRESS LD H,(IX+1) ; LD DE,0 ;D=TRACK=0 : E=SECTOR=0 ; VLOOP: CALL VMESG ;PRINT VERIFY MESG. ; LD A,D ;A=TRACK LD (VTRK),A ;SET TRACK ; VLOP1: LD C,E ;BC=SECTOR LD B,0 PUSH HL ;SAVE SECTAB POINTER ADD HL,BC ;ADD SECTOR TO TABLE ; LD A,(HL) ;A=PHYSICAL SECTOR POP HL ;RESTORE HL ; CP 0FFH ;SEE IF DONE JR Z,NTRK ;JMP IF DONE ; CP 0FEH ;SEE IF 1ST PASS DONE JR NZ,NEND ;JMP IF 1ST PASS NOT DONE. ; LD E,1 ;SET FOR 2ND PASS. JR VLOP1 ;START 2ND PASS. ; NENDº INC Å ;INÃ SECTOÒ COUNT. INC E ; LD (VSEC),A ;SET SECTOR PUSH DE ; PUSH HL CALL READ ;READ SECTOR POP HL ; OR A LD DE,RMESG ;PNTR TO ERR MESG JR Z,SKIP ;JMP IF NO ERROR PUSH HL CALL PRNT ;CALL IF ERROR ; LD DE,VMSGI CALL PRNT ; LD A,1 ;SET ERROR FLAG LD (EFLAG),A POP HL POP DE JR NTRK ;SKIP BAD TRACK ; SKIP: POP DE ;RESTORE TRK-SECT JR VLOP1 ;GO READ NEXT SECTOR ; NTRK: LD E,0 ;SECT=0 INC D ;INC TRACK LD A,(IX+LTRK) ;SEE IF LAST TRACK CP D JR NZ,VLOOP ;LOOP IF NOT DONE ; POP BC ;B=DSKDEF1 ; SSD2: LD A,(EFLAG) ;ERR FLAG OR A ;SET FLAGS JR Z,NBAD ;JMP IF NO ERRORS ; LD DE,EMESG ;ERR MESG. CALL PRNT ; NBAD: CALL INIT ;INIT TRACK 0 LD DE,FMESG ;PNTR. TO END MESG. CALL PRNT ; LD DE,FATAL BAD1: LD HL,(HLTMP) LD A,H OR L JR Z,NTVRT LD (HL),0 NTVRT: LD A,(IBUF) OR A JR NZ,FINI CALL PRNT ; BAGN: CALL CIN CP 'R' ;SEE IF ASCII R JP Z,100H ;START AGAIN IF R ; CP CR ;SEE IF CR JÒ NZ,BRESP ; FINI: LD A,(DRVM) CP 'A' JR NZ,NTA LD HL,(HLTMP) LD A,L OR H JR Z,NVT LD A,'A' LD (DRVT),A LD A,(IFLAG) OR A LD DE,IMSG2 JR NZ,NVT1 LD DE,(VTMSGP) CALL PRNT LD DE,DRVT CALL PRNT LD DE,VT2 CALL PRNT JR FLOP NVT: LD DE,SYSM NVT1: CALL PRNT FLOP: CALL CIN CP 0DH JR NZ,FLOP NTA: JP 0 ; BRESP: LD DE,BKSP CALL PRNT JR BAGN ; VMESG: PUSH HL ;SAVE REGS. PUSH DE PUSH BC ; LD A,D ;A=TRACK CALL ASCII ;COMVERT TO ASCII LD (VMTRK),BC ;STORE STRING ; LD DE,VMSG ;PNTR. TO VER.MESG. CALL PRNT ; POP BC POP DE ;RESTORE REGS. POP HL RET ; ; WRTT: PUSH IX ;SAVE IX ; LD HL,FRMDTX ;MOVE RAMDATX LD DE,RAMDATX LD BC,RAMLEN LDIR ; LD IX,RAMDATX ;SET RAMDATX FOR FORMAT ; LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,DISCIO ;OFFSET TO DISCIO JMP ADD HL,DE ;ADD TO HL ; CALL JPHL ; POP IX ;RESTORE IX RET ; JPHL: JP (HL) ;GO TO DISK I/O ; SWRT: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,WROFF ;OFFSET TO WRITE JMP ADD HL,DE ;ADD TO HL LD C,1 JP (HL) ;GO TO WRITE ; READ: PUSH IX ;SAVE IX ; LD HL,VRMDTX ;MOVE RAMDATX LD DE,RAMDATX LD BC,RAMLEN LDIR ; LD IX,RAMDATX ;SET RAMDATX FOR VERIFY ; LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,RDBLK ;OFFSET TO RDBLK JMP ADD HL,DE ;ADD TO HL ; CALL JPHL ; POP IX RET ; SELDSK: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,SELOFF ;OFFSET TO SELDSK JMP ADD HL,DE ;ADD TO HL LD E,1 JP (HL) ;GO TO SELDSK ; HOME: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,HMOFF ;OFFSET TO HOME JMP ADD HL,DE ;ADD TO HL JP (HL) ;GO TO HOME ; SELTRK: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,TRKOFF ;OFFSET TO SETTRK ADD HL,DE ;ADD TO HL JP (HL) ;GO TO SETTRK ; SELSEC: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,SECOFF ;OFFSET TO SETSEC ADD HL,DE ;ADD TO HL JP (HL) ;GO TO SETSEC ; SETDMA: LD HL,(WBOOT) ;GET WARM BOOT ADDRESS LD DE,DMAOFF ;OFFSET TO SETDMA ADD HL,DE ;ADD TO HL JP (HL) ;GO TO SETDMA ; INIT: LD C,0 ;TRACK=0 CALL SELTRK ; LD C,1 ;SECTOR=1 CALL SELSEC ; LD BC,IDAT ;DMA ADDR.=IDAT CALL SETDMA ; CALL SWRT ;WRITE SECTOR OR A ;CHECK FOR ERRORS JR NZ,WERROR ;JMP IF ERROR ; LD C,9 ;SECTOR=9 CALL SELSEC ; CALL SWRT ;WRITE SECTOR OR A ;CHECK FOR ERRORS JR NZ,WERROR ;JMP IF ERROR ; LD C,2 ;SECTOR 2 CALL SELSEC ; LD BC,(DPBP) CALL SETDMA ; CALL SWRT OR A JR NZ,WERROR ; RET ; ; WERROR: LD DE,WERR ;PNTR. T0 WRT. ERROR ; ERROR: CALL PRNT LD DE,FATAL ;PNTR. TO FATAL ERR MESG. JP BAD1 ; PRNT: LD C,PBUFF ;PRINT BUFFER COMMAND JP SYS ;JUMP TO SYSTEM ; ASCII: LD C,ASC0 ;C=ASCII 0 ALOP: SUB 10 ;SUB 10 JR C,ADN ;JMP IF CY=1 ; INC C ;INC CHAR. JR ALOP ;CONTINUE ; ADN: ADD A,3AH ;FIX CHAR. LD B,A RET ; CIN: LD C,RDCON ;USE DIRECT CONSOLE I/O TO LD E,0FFH ;WAIT FOR A CHARACTER. CALL SYS OR A JR Z,CIN ; CHKIN: CP ASCA ;SEE IF LESS THAN ASCII "A" JR C,NALPH ;JMP IF LESS THAN "A" ; AND 0DFH ;FORCE TO UPPER CASE ; NALPH: LD E,A CP SPACE ;SEE IF CONTROL CHAR. JR NC,NECHO ;JMP IF NOT CONTROL CHAR. ; CP CTLC ;SEE IF CONTROL-C JP Z,0 ; LD E,SPACE ; NECHO: PUSH AF ;SAVE REGS. PUSH BC ; LD C,RDCON ;ECHO CHAR. CALL SYS ; POP BC ;RESTORE REGS. POP AF ; RET ; EFLAG: DB 0 IFLAG: DB 0 IPNT: DW 0 ICNT: DB 0 HLTMP: DW 0 DPBP: DW 0 MSGP: DW 0 VTMSGP: DW 0 ; MESG1: DB 1AH,0,0,0,'Micro-Decision FORMAT program Rev. 2.4 Copyright 1984' DB 0DH,0AH,'Morrow Designs, Inc. San Leandro, CA',0AH,0DH,'$' GDRV: DB 0AH,0DH,'Disk drive to be used (A-E) $' ; BKSP: DB 8,20H,8,'$' CRLF: DB 0AH,0DH,'$' MESG2: DB 0AH,0DH,'Insert diskette to be formatted in drive ' DRVM: DB 'A, then press [RETURN] $' SDMSG: DB CR,LF,'Single or double sided format (S or D) $' DM: DB 8,'D$' ; ; DMSG: DB 0DH,0AH,'Double density -- $' SNMSG: DB 'Single sided format',0DH,0AH,'$' DBMSG: DB 'Double sided format',0DH,0AH,'$' M256: DB CR,LF,'Double density 256 bytes/sector format',CR,LF,'$' M512: DB CR,LF,'Double density 512 bytes/sector format',CR,LF,'$' ; FMSGI: DB 0DH,'Formatting track ' MTRK: DB '00 $' FORMSG EQU FMSGI ; WERR: DB 0DH,0AH,'Write error',0DH,0AH,'$' RMESG: DB 0DH,0AH,'Read error',0DH,0AH,'$' EMESG: DB 0AH,0DH,'Some errors were found on this diskette, ' DB 'use at your own risk.$' FMESG: DB 0DH,0AH,0AH,'Formatting done$' FATAL: DB 0DH,0AH,'Press R to start again, or [RETURN] to return to CP/M $' VMSGI: DB 0AH,0DH,'Verifying track ' VMTRK: DB '00 $' VMSG EQU VMSGI+1 IDSK: DB 'Invalid disk parameter block',0DH,0AH,'$' SYSM: DB 0DH,0AH,0AH,'Insert the system diskette in drive A, then press [RETURN] $' VTMSG: DB 0DH,0AH,0AH,'Your left drive is being re-assigned as drive $' VTMSGD: DB 0DH,0AH,0AH,'Your lower drive is being re-assigned as drive $' VTMSG1: DB 0DH,0AH,0AH,'Your drive is being re-assigned as drive $' DRVT: DB 'A.$' VT1: DB 0DH,0AH,'Insert the diskette to be formatted and press [RETURN] $' VT2: DB 0DH,0AH,'Insert the system diskette, then press [RETURN] $' IMSG1: DB 0DH,0AH,'Insert the DESTINATION diskette, then press [RETURN] $' IMSG2: DB 0DH,0AH,'Insert the SOURCE diskette, then press [RETURN] $' ; FRMDTX: HSTDSK: DB 0 HSTTRK: DB 0 HSTSEC: DB 0 ; SECCNT: DB 1 RETRY: DB 5 HSTBUF: DW TRKBUF ; ERFLAG: DB 0 PHYTRK: DB 0 PHYHD: DB 0 ; IOADD: DW WRIO SECSIZ: DW 0 ; STADD: DS (7),0 ; CMDCNT: DB 6 FDCCMD: DB FMTCMD HDDRV: DB 0 N: DB 0 SC: DB 0 GPL: DB 0 DAT: DB 0 ; RAMLEN EQU $-FRMDTX ; ; VRMDTX: VDSK: DB 0 VTRK: DB 0 VSEC: DB 0 ; VCNT: DB 1 VRETRY: DB 6 VBUF: DW TRKBUF ; VERFLG: DB 0 VPHTRK: DB 0 VPHYHD: DB 0 ; VADD: DW 0 VSIZE: DW 0 ; VSTAT: DS (7),0 ; CMDBUF: DS (10),0 ; FTAB1K: DW SECTB1K DB 3 ;N = SECTOR SIZE CODE DB 5 ;SC = SECTORS PER TRACK DB 95 ;GPL = GAP3 LENGTH DB 0E5H ;D = FILL BYTE DB 40 ;LAST TRACK ; DW SECTB1K DB 3 ;N = SECTOR SIZE CODE DB 5 ;SC = SECTORS PER TRACK DB 95 ;GPL = GAP3 LENGTH DB 0E5H ;D = FILL BYTE DB 80 ;LAST TRACK ; SECTB1K:DB 1,2,3,4,5,0FFH,0FEH ; FTAB256:DW SCTB256 DB 1 DB 16 DB 50 DB 0E5H DB 40 ; DW SCTB256 DB 1 DB 16 DB 50 DB 0E5H DB 80 ; SCTB256:DB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,0FFH,0FEH ; FTAB512:DW SCTB512 DB 2 DB 8 DB 80 DB 0E5H DB 40 ; DW SCTB512 DB 2 DB 8 DB 80 DB 0E5H DB 80 ; SCTB512:DB 1,2,3,4,5,6,7,8,0FFH,0FEH ; ; DPBS: DS 9,0 DW 40 DB 4 DB 15 DB 1 DW 94 DW 127 DB 0C0H DB 0 DW 32 DW 2 DB 0E1H DS 80H-25,0 ; DPBD: DB 0 DB 4 DS 7,0 DW 40 DB 4 DB 15 DB 1 DW 194 DW 191 DB 0E0H DB 0 DW 48 DW 2 DB 89H DS 80H-25,0 ; IDAT EQU $ ; .PHASE 0FE00H ; NOP NOP NOP LD A,0C9H LD (0FDFFH),A CALL 0FDFFH RADD: LD HL,-2 ADD HL,SP LD E,(HL) INC HL LD D,(HL) LD HL,EMSG-RADD ADD HL,DE EX DE,HL LD SP,0FF00H OUT (0F6H),A CALL MESG JP BTERR ;JMP TO ROM ; ; EMSG: DB CR,LF,'Not a SYSTEM Diskette.',CR,LF,0 ; DS (80H),0 ; .DEPHASE ; END