CQ  8   0K Double-Sided  ((n(** NONE ** \^&)   Image file created by unregistered CopyQM #' 1  @   V BIOS86 A86   BIOS86 A86  !"# BIOS86 A86 _$%&'()  CLDR207 A86 -*+, 3 FORMAT A86 -./0123456789:;< FORMAT A86 >=>?@  LBIOS207A86 SABCDEF  ASCII LIB G  BIOSDEF LIB HI  CIOTABLELIB JK  CPM86SCBLIB L  CPM86SYSLIB $MNO  DEF6821 LIB P  DEF6845 LIB Q  DEF8253 LIB R  DEF8259ALIB ST  EP2DEF LIB UV  EXTRAOPSLIB W  LABDEF LIB X  PATHNDLRLIB YZ  R85PKG LIB =[\]^  RUN8085 LIB _  SBCDEF LIB `  TIMEDRVRLIB Fabcde  TIMERDEFLIB f  Z207DEF LIB gh 1 Z207DRVRLIB ijklmnopqrstuvwx Z207DRVRLIB yz  Z217DEF LIB ;{|}~  Z217DRVRLIB _  ZDPEDEF LIB   ZGDPDEF LIB   ZINT LIB   ZKEYBD LIB  ZMEMMAP LIB   ZMTR100 LIB   ZPORTS LIB   ZVIDEO LIB TITLE 'CP/M-86 BIOS 23 SEP 83' ;*** ; ; THIS IS THE ZENITH DATA SYSTEMS' BIOS FOR CP/M-86. ; ; COPYRIGHT (C) 1983, ZENITH DATA SYSTEMS CORP. ; ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; FALSE EQU 0 TRUE EQU NOT FALSE EXPER EQU FALSE ;EXPERIMENTAL R8085 EQU TRUE ;RUNNING 8085 PROCESSOR SUPPORTED ;*** EQUATES ; DSEG INCLUDE ZMEMMAP.LIB INCLUDE ASCII.LIB INCLUDE DEF6821.LIB INCLUDE DEF6845.LIB INCLUDE DEF8253.LIB INCLUDE DEF8259A.LIB INCLUDE EP2DEF.LIB INCLUDE SBCDEF.LIB INCLUDE TIMERDEF.LIB INCLUDE Z207DEF.LIB INCLUDE Z217DEF.LIB INCLUDE ZINT.LIB INCLUDE ZMTR100.LIB INCLUDE ZPORTS.LIB INCLUDE ZGDPDEF.LIB INCLUDE ZKEYBD.LIB INCLUDE ZVIDEO.LIB INCLUDE CPM86SYS.LIB INCLUDE CPM86SCB.LIB INCLUDE CIOTABLE.LIB INCLUDE ZDPEDEF.LIB INCLUDE LABDEF.LIB IF R8085 INCLUDE RUN8085.LIB ENDIF ;** MISCELLANEOUS EQUATES ; ORG 0DFH*4 ZPATVEC RW 2 ;SWI VECTOR FOR PATCHES TO CCP/BDOS ORG BDOSE*4 BDOSVEC RW 2 ;SWI VECTOR FOR BDOS ENTRY INCLUDE EXTRAOPS.LIB ;* DEVICE DRIVER ENTRY JUMP VECTOR OFFSETS ; DDSEL EQU 0 ;SELECT DDRDT EQU 3 ;READ TRACK DDWRT EQU 6 ;WRITE TRACK DDMNT EQU 9 ;MOUNT DDFMT EQU 12 ;FORMAT DDWPC EQU 15 ;WRITE PROTECT CHECK ;* DISK OPERATIONS IN PROGRESS FLAGS ; DSKOPS EQU 04 1B ;1ST TIME AFTER WARM BOOT SELECTION DSKOPR EQU 0 10B ;READ DSKOPW EQU 0i 100B ;WRITE DSKOPRA EQU 00001000B ;READ ADDRESS HEADER DSKOPF EQU 00010000B ;FORMAT DSKOPWP EQU 0010& B ;WRITE PROTECT CHECK DSKOPI EQU 010 B ;INIT DSKOPRD EQU 10HB ;READY ;* DISK BUFFER HANDLING DEFINITIONS ; BUFMCNT EQU 7 ;MAXIMUM # OF BUFFERS BUFMNS EQU 26 ;MAXIMUM NUMBER OF SECTORS BUFSIZ EQU 9*1024 ;BUFFER SIZE (MAX TRACK SIZE) ; BUFFER HEADER INFO ORG 0 BUFHDR RB 0 BUFFWD RW 1 ;FORWARD CHAIN POINTER BUFBAK RW 1 ;BACKWARD CHAIN POINTER BUFDRV RB 1 ;DRIVE # BUFPDRV RB 1 ;MAPPED DRIVE # (PHYSICAL TABLE #) BUFDPE RW 1 ;ADDRESS OF DPE BUFTRK RW 1 ;TRACK # BUFWRF RB 1 ;BUFFER DIRTY FLAG BUFSECF RW 1 ;ADDRESS OF DIRTY SECTOR FLAGS BUFERR RB 1 ;TRACK ERROR FLAG BUFERRF RW 1 ;ADDRESS OF SECTOR ERROR FLAGS BUFBUF RW 0 ;ADDRESS OF BUFFER AREA BUFBUFO RW 1 ; OFFSET BUFBUFS RW 1 ; SEGMENT BUFHDRL EQU OFFSET $ - OFFSET BUFHDR ;LENGTH OF BUFFER HEADER INFO EJECT ;*** SOME DEFINITIONS OF SLOTS WITHIN CCP ; CSEG ORG CPMCCP  ;! CCP: # ;COLD BOOT ENTRY ;! ORG CPMCCP+6 ;! CCPRET: 0 ;WARM BOOT ENTRY ;! DSEG ORG CPMCCP+0009H 9 ;! CCPCMD RB 0 ;COMMAND BUFFER ;! ORG CPMCCP+0939H x ;! DFTDRV RB 0 ;DEFAULT DRIVE ;! ;*** SOME DEFINITIONS OF SLOTS WITHIN BDOS ; DSEG ORG CPMCCP+22E6H ;! KBCHAR RB 0 ;1 CHAR TYPE AHEAD BUFFER ;! EJECT ;*** BIOS ENTRY JUMP TABLE ; CSEG ORG CPMBIOS BIOSJMP: JMP CBOOTE ;COLD BOOT JMP WBOOTE ;WARM BOOT JMP CONSTE ;CONSOLE STATUS JMP CONINE ;CONSOLE INPUT JMP CONOUTE ;CONSOLE OUTPUT JMP LSTOUTE ;LIST OUTPUT JMP PUNOUTE ;PUNCH OUTPUT JMP RDRINE ;READER INPUT JMP HOMEE ;HOME HEAD JMP SETDSKE ;SET DISK DRIVE JMP SETTRKE ;SET TRACK JMP SETSECE ;SET SECTOR JMP SETDMAE ;SET DMA OFFSET JMP READE ;READ CP/M SECTOR JMP WRITEE ;WRITE CP/M SECTOR JMP LSTSTE ;LIST STATUS JMP SECTRNE ;SECTOR TRANLATE JMP SDMABE ;SET DMA SEGMENT JMP GETMRTE ;GET MEM DESCRIPTION TABLE OFFSET JMP GETIOBE ;GET I/O MAPPING BYTE JMP SETIOBE ;SET I/O MAPPING BYTE JMP FORMATE ;FORMAT JMP RDTRKE ;READ TRACK JMP WRTRKE ;WRITE TRACK JMP WPCE ;WRITE PROTECT CHECK JMP CLRBUFD ;CLEAR BUFFERS FOR D RIVE JMP GETBTE ;GET BIOS TABLES EJECT ;*** COLD BOOT ENTRY ; CBOOTE: CLI ;INSURE I'M NOT DISTURBED ; INITIALIZE REGISTERS MOV AX,CS MOV DS,AX MOV SS,AX LEA SP,STACK ADD NXTAVL,AX ;MEMORY TABLE (ADJUST FOR LOAD ADDRESS) MOV IFLAG,0 ;CLEAR BIOS INTERRUPT HANDLER FLAGS IF R8085 MOV R85MEM,0 ;INDICATE 8085 PROCESSOR NOT RUNNING MOV R85BCS,CS ;SAVE (CS) FOR RUNTIME PACKAGE ENDIF ; INITIALIZE PARITY GENERATION & SIZE MEMORY (IN 1K CHUNKS) PUSH DS MOV AL,ZMCLPZ+ZRM2 ;TURN OFF PARITY CHECKING OUT ZMCL,AL OUT 098H,AL OUT 099H,AL OUT 09AH,AL OUT 09BH,AL OUT 09CH,AL OUT 09DH,AL OUT 09EH,AL OUT 09FH,AL XOR AX,AX ;START AT SEGMENT 0 MOV DX,AX ;INIT TOP OF MEMORY PARAGRAPH CLD MEMIL: MOV DS,AX ;SET UP SEGMENT REGISTERS MOV ES,AX MOV AX,.0 ;GET FIRST WORD MOV BX,AX ;SAVE A COPY INC AX ;BUMP VALUE INC WORD PTR .0 ;BUMP MEMORY CMP AX,.0 ;Q. ARE THEY THE SAME JE MEMIA ; BR IF YES CMP DX,0 ;Q. 1ST SECTION OF CONTIGUOUS MEMORY JNE MEMIC ; BR IF ALREADY ESTABLISHED MOV DX,DS JMPS MEMIC MEMIA: MOV .0,BX ;RESTORE VALUE XOR SI,SI ;SET UP REGS FOR MOVE XOR DI,DI MOV CX,512 ;GET NUMBER OF WORDS TO MOVE REP MOVSW ;MOVE WORDS ONTO THEMSELVES MEMIC: MOV AX,DS ;POINT TO NEXT SEGMENT ADD AX,1024/16 JNZ MEMIL ; LOOP IF NO WRAP AROUND POP DS MOV TOPMEM,DX ;SAVE AS TOP OF MEMORY MOV AL,ZMCLPK+ZMCLPZ+ZRM2 ;TURN ON PARITY CHECKING OUT ZMCL,AL OUT 098H,AL OUT 099H,AL OUT 09AH,AL OUT 09BH,AL OUT 09CH,AL OUT 09DH,AL OUT 09EH,AL OUT 09FH,AL ; INCASE BOOTING WAS DONE ON Z217, PICK UP PARTITION LIMITS ; FROM LOW MEMORY XOR AX,AX MOV ES,AX MOV AX,ES: .0 MOV Z217BP,AX MOV AX,ES: .2 MOV Z217EP,AX ; INITIALIZE ALL VECTORS (EXCEPT WHERE MONITOR DATA SEGMENT INFO ; IS) TO POINT TO WILD INTERRUPT HANDLER PUSH DS XOR AX,AX MOV DS,AX MOV ES,AX MOV WORD PTR .0,OFFSET INTWILD ;INIT VECTORS FOR WILD INT MOV .2,CS MOV SI,0 MOV DI,4 MOV CX,(256-2)*4/2 CLD REP MOVSW ; INITIALIZE SOFTWARE INTERRUPT VECTORS MOV WORD PTR .0,OFFSET INTDIV0 ;DIVIDE BY ZERO MOV .2,CS MOV BDOSVEC,CPMBDOS ;BDOS CALLS MOV BDOSVEC+2,CS MOV ZPATVEC,OFFSET ZPATCH ;PATCHES TO CCP/BDOS MOV ZPATVEC+2,CS POP DS ; INITIALIZE HARDWARE INTERRUPT VECTORS XOR AX,AX MOV ES,AX LEA SI,HINTVO MOV DI,ZINTMT*4 MOV CX,HINTVON CLD INHV: MOVSW ADD DI,2 LOOP INHV ; INITIALIZE MASTER 8259A MOV AL,ICW1OP+ICW1LT+ICW1ADI+ICW1I4 OUT Z8259AM+ICW1,AL ;LEVEL TRIGGERED, ADI OF 4 MOV AL,ZINTMT OUT Z8259AM+ICW2,AL ;BASE TRAP VECTOR MOV AL,1 SHL ZINTSLV OUT Z8259AM+ICW3,AL ;INDICATE SLAVE IR LINE MOV AL,ICW4SFN+ICW4UPM OUT Z8259AM+ICW4,AL ;SPECIAL FULLY NESTED, 8086 PROCESSOR MOV AL,0FFH-(1 SHL ZINTKD)-(1 SHL ZINTTIM)-(1 SHL ZINTEI) OUT Z8259AM+OCW1,AL ;ENABLE ONLY DESIRED IR LINES ; INITIALIZE SLAVE 8259A MOV AL,ICW1OP+ICW1LT+ICW1ADI+ICW1I4 OUT Z8259AS+ICW1,AL ;LEVEL TRIGGERED, ADI OF 4 MOV AL,ZINTST OUT Z8259AS+ICW2,AL ;BASE TRAP VECTOR MOV AL,ZINTSLV OUT Z8259AS+ICW3,AL ;SLAVE ID MOV AL,ICW4UPM OUT Z8259AS+ICW4,AL ;8086 PROCESSOR MOV AL,0FFH OUT Z8259AS+OCW1,AL ;DISABLE ALL IR LINES ; INITIALIZE CHARACTER I/O PORTS CALL INCRT ;CRT: CALL INSERA ;SERIAL PORT A CALL INSERB ;SERIAL PORT B CALL INPPRT ;LIGHTPEN, VSYNC , & PARALLEL PRINTER CALL INDUMMY ;DUMMY I/O MOV AX,0 ;INDICATE NO LIGHT PEN HIT MOV ES,AX MOV ES: LPENHF,0 ; MOVE ROM MONITOR DATA AREA TO BIOS XOR AX,AX ;GET MONITOR DATA AREA SEGMENT MOV ES,AX MOV ES,ES:.MTRDSEG MOV AX,ES:MTRDSZ ;GET FREE MEMORY CALL GETMEM JNC MVMDA ; BR IF AVAILABLE LEA SI,MTRMSG CALL PMSG JMP SYSHLT MVMDA: MOV CX,ES:MTRDSZ ;MOVE MONITOR DATA AREA MOV SI,0 MOV DI,0 PUSH DS MOV DX,ES MOV DS,DX MOV ES,AX CLD REP MOVSB POP DS XOR DX,DX ;UPDATE LOW MEMORY POINTER MOV ES,DX ; TO MONITOR DATA AREA MOV ES:.MTRDSEG,AX ; CALL INTIM ;INITIALIZE TIMER STI ;ALLOW INTERRUPTS NOW ; INITIALIZE HOST BUFFERING SCHEME CALL INBUF ; INITIALIZE LOGICAL DRIVE TO PHYSICAL DRIVE MAP XOR AX,AX MOV ES,AX MOV ES,ES: .MTRDSEG ;GET ADDRESS OF MONITOR DATA AREA CMP ES: MTRBI,2 ;Q. Z217 BOOTED JNE CBINDRV1 ; BR IF NOT CALL IN217 CALL IN207 JMPS INITMT CBINDRV1: CALL IN207 CALL IN217 ; INIT MEMORY REGION DESCRIPTION TABLE INITMT: MOV AX,TOPMEM ;CALC # PARAGRAPHS SUB AX,NXTAVL MOV MEMAVL,AX ; GET ALTERNATE CHARACTER FONT INFO GALTCHR: CALL ALTCHR ; PRINT SIGNON MESSAGE MOV AL,DEFIOB ;SET DEFAULT I/O BYTE MOV IOBYTE,AL LEA SI,SIGNON CALL PMSG ; ENTER CP/M COMMAND PROCESSOR MOV AX,CS ;INIT (ES) MOV ES,AX CMP AUTOCBC,0 ;Q. AUTO COMMAND ON COLD BOOT JE CBOOTCCP ; BR IF NOT XOR CH,CH ;ZERO COMMAND BUFFER MOV CL,CCPCMD INC CX LEA DI,CCPCMD+1 CLD MOV AL,0 REP STOSB MOV CL,AUTOCBC ;MOVE IN AUTO COMMAND INC CX LEA SI,AUTOCBC LEA DI,CCPCMD+1 REP MOVSB CBOOTCCP: MOV AX,BIOSWJ ;RESET COLD BOOT JMP TO ADD AX,3 ; POINT TO WARM BOOT MOV BIOSCJ,AX MOV CL,0 ;DEFAULT DISK IS A: JMP CCP CBX1 EQU OFFSET $ DSEG ORG OFFSET BIOSJMP RB 1 BIOSCJ RW 1 RB 1 BIOSWJ RW 1 CSEG ORG CBX1 EJECT ;** WARM BOOT ENTRY ; WBOOTE: CALL CLRBUFA ;CLEAR ALL HOST BUFFERS IF R8085 ; TERMINATE 8085 PROCESS IF ONE IS RUNNING CMP R85MEM,0 ;Q. 8085 RUNNING JE WBOOTE1 ; BR IF NOT PUSHF ;I DON'T WANT TO BE DISTURBED CLI MOV ES,R85MEM ;INDICATE TO 8085 TERMINATE MOV ES:COMFLG,COMTERM MOV AL,ZPSPPS5+ZPSPI88 ;SWAP TO 8085 TEMPORARILY OUT ZPSP,AL MOV R85MEM,0 ;INDICATE NO 8085 PROCESS RUNNING POPF ;RE-ESTABLISH INTERRUPT STATUS ENDIF WBOOTE1: CMP AUTOWBC,0 ;Q. AUTO COMMAND ON WARM BOOT JE WBOOTE2 ; BR IF NOT XOR CH,CH ;ZERO COMMAND BUFFER MOV CL,CCPCMD INC CX LEA DI,CCPCMD+1 MOV AX,DS MOV ES,AX CLD MOV AL,0 REP STOSB MOV CL,AUTOWBC ;MOVE IN AUTO COMMAND INC CX LEA SI,AUTOWBC LEA DI,CCPCMD+1 REP MOVSB WBOOTE2: JMP CCPRET ;ENTER CP/M COMMAND PROCESSOR ;** CONSOLE STATUS ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=STATUS ; T0=NO CHARACTER AVAILABLE , 0FFH=CHARACTER AVAILABLE ; USES: ALL ; CONSTE: MOV AL,IOBYTE ;GET IOBYTE VALUE SHL AL,1 ;ADJUST VALUE CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW CRTTBL DW 0 DW SERBTBL TEST BX,BX ;Q. SPECIAL CASE BAT: JNZ CONSTE1 ; BR IF NOT MOV AL,IOBYTE ;GET IOBYTE VALUE SHR AL,1 ;ADJUST VALUE CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW DUMMYTBL DW SERBTBL DW CRTTBL CONSTE1: CALL ISCIO ;CALL CIO HANDLER RET ;** CONSOLE INPUT ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=CHARACTER READ FROM CONSOLE ; USES: ALL ; CONINE: MOV AL,IOBYTE ;GET IOBYTE VALUE SHL AL,1 ;ADJUST VALUE CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW CRTTBL DW 0 DW SERBTBL TEST BX,BX ;Q. SPECIAL CASE BAT: JZ RDRINE ; BR IF YES CALL IDCIO ;CALL CIO HANDLER RET ;** CONSOLE OUTPUT ENTRY ; ; ENTRY: (CL)=CHARACTER TO BE OUTPUT ; EXIT: NONE ; USES: ALL ; CONOUTE: MOV AL,IOBYTE ;GET IOBYTE VALUE SHL AL,1 ;ADJUST VALUE CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW CRTTBL DW 0 DW SERBTBL TEST BX,BX ;Q. SPECIAL CASE BAT: JZ LSTOUTE ; BR IF YES JMP ODCIO ;RETURN VIA CIO HANDLER ;** LIST OUTPUT ENTRY ; ; ENTRY: (CL)=CHARACTER TO BE OUTPUT ; EXIT: NONE ; USES: ALL ; LSTOUTE: MOV AH,CL ;SAVE CHARACTER MOV AL,IOBYTE ;GET IOBYTE VALUE MOV CL,5 ;ADJUST VALUE SHR AL,CL MOV CL,AH ;GET CHARACTER CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW CRTTBL DW PPRTTBL DW SERBTBL JMP ODCIO ;RETURN VIA CIO HANDLER ;** PUNCH OUTPUT ENTRY ; ; ENTRY: (CL)=CHARACTER TO BE OUTPUT ; EXIT: NONE ; USES: ALL ; PUNOUTE: MOV AH,CL ;SAVE CHARACTER MOV AL,IOBYTE ;GET IOBYTE VALUE MOV CL,3 ;ADJUST VALUE SHR AL,CL MOV CL,AH ;GET CHARACTER CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW DUMMYTBL DW SERBTBL DW CRTTBL JMP ODCIO ;RETURN VIA CIO HANDLER ;** READER INPUT ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=CHARACTER READ ; USES: ALL ; RDRINE: MOV AL,IOBYTE ;GET IOBYTE VALUE SHR AL,1 ;ADJUST VALUE CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW DUMMYTBL DW SERBTBL DW CRTTBL CALL IDCIO ;CALL CIO HANDLER RET ;** HOME HEAD ENTRY ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; HOMEE: CALL CHKDBD ;Q. ANY DIRTY BUFFERS FOR REQ DRIVE TEST AL,AL JNZ HOMEE1 ; BR IF YES CALL CLRBUFD ;FORCE PHYSICAL I/O HOMEE1: MOV CX,0 ;SET REQUESTED TRACK # = 0 JMP SETTRKE ;JOIN SET TRACK CODE ;** SET DISK DRIVE ENTRY ; ; ENTRY: (CL)=REQUESTED DRIVE ; (DL)=LSB INDICATES 1ST TIME SINCE WARM BOOT SELECT ; 0=1ST TIME , 1=SUBSEQUENT TIMES ; EXIT: (BX)=RESULTS ;  0=ERROR , NOT 0=NO ERROR ; USES: ALL ; SETDSKE: PUSH ES MOV REQDRV,CL ;SAVE REQUESTED DRIVE CMP CL,NDISKS ;CHECK IF IN RANGE JAE SETDSKE5 ; BR IF NOT MOV AL,CL ;CONVERT LOGICAL DRIVE # TO CBW ; PHYSICAL DRVIE # MOV BX,AX MOV AL,BDMAP[BX] MOV PHYDRV,AL MOV BL,DPEL ;COMPUTE ADDRESS OF DPE MUL BL ADD AX,OFFSET DPEBASE MOV PHYDPE,AX ;SAVE IT TEST DL,1 ;CHECK IF 1ST LOGIN JNZ SETDSKE9 ; BR IF NOT CALL CLRBUFD ;CLEAR HOST BUFFERS FOR THIS DRIVE MOV PREREAD,0 ;INDICATE DON'T DO PREREAD CALL SETUP ;GET A BUFFER TO USE CMP BUFERR[BX],0 ;Q. ABORT JNE SETDSKEA ; BR IF YES MOV AL,DDSEL ;CALL DEVICE DRIVER TO DO SELECT CALL DRVR CALL CLRBUFD ;GIVE BACK BUFFER CMP PHYDPE,0 ;Q. ERROR JNE SETDSKE9 ; BR IF NO ERROR RETURN BY DRIVER ; ERROR DURING SETDSK SETDSKE5: MOV AL,REQDRV ;CHECK IF REQUESTED DRIVE CMP AL,DFTDRV ; WAS TO BE DEFAULT DRIVE JNE SETDSKE6 ; BR IF NOT MOV DFTDRV,0 ;FORCE DEFAULT DRIVE TO 'A:' SETDSKE6: MOV PHYDPE,0 ;INDICATE ERROR (ADDR OF DPE = 0) ; RETURN ADDRESS OF DPE TO CALLER SETDSKE9: MOV BX,PHYDPE POP ES RET ; ERROR DURING SETUP SETDSKEA: CALL CLRBUFD ;GIVE BACK BUFFER JMPS SETDSKE5 ;** SET TRACK ENTRY ; ; ENTRY: (CX)=TRACK # ; EXIT: NONE ; USES: ALL ; SETTRKE: MOV REQTRK,CX ;SAVE AS REQUESTED CP/M TRACK # RET ;** SET SECTOR ENTRY ; ; ENTRY: (CX)=SECTOR # (IN RANGE 1 TO SPT) ; EXIT: NONE ; USES: ALL ; ; *** NOTE *** ; IT IS ASSUMED ON ENTRY THAT THE SECTOR NUMBER IS IN THE RANGE 1 TO ; 'CP/M SECTORS PER TRACK'. THEREFORE, ONLY THE VALUE PASSED ; IN REGISTER CL IS USED. ; INTERNALLY THE BIOS WANTS SECTOR NUMBERS IN THE RANGE ; 0 TO SPT-1. THEREFORE, BEFORE SAVING THE SECTOR NUMBER, ; IT IS DECREMENTED. ; SETSECE: DEC CL ;PUT INTO RANGE 0 TO SPT-1 XOR CH,CH ;ZERO HIGH ORDER BYTE MOV REQSEC,CX ;SAVE AS REQUESTED CP/M SECTOR # RET ;** SET DMA OFFSET ENTRY ; ; ENTRY: (CX)=DMA POINTER OFFSET ; EXIT: NONE ; USES: ALL ; SETDMAE: MOV DMAPTR,CX ;SAVE AS DMA POINTER OFFSET RET ;** READ CP/M SECTOR ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; 0=NO ERROR , 1=ERROR ; USES: ALL ; READE: PUSH ES MOV PREREAD,1 ;DO PREREAD CALL SETUP ;CALL R/W COMMON SETUP ROUTINE CMP BUFERR[BX],0 ;Q. ERROR DURING SETUP JNE READE1 ; BR IF YES ; HOST BUFFER CONTAINS REQUESTED CP/M SECTOR. ; COPY IT TO USER BUFFER. PUSH DS LES DI,DWORD PTR DMAPTR ;GET DMA POINTER LDS SI,DWORD PTR BUFBUF[BX] ;COMPUTE START OF REQ CP/M SECTOR ADD SI,AX ; IN HOST BUFFER CLD REP MOVSW ;MOVE DATA FROM HOST TO USER BUFFER POP DS ; CALL CPSEC ;INDICATE ERROR STATUS OR DSKOP,DSKOPR CALL ABTIGN AND DSKOP,NOT DSKOPR READE1: MOV AL,BUFERR[BX] POP ES RET ;** WRITE CP/M SECTOR ENTRY ; ; ENTRY: (CL)=TYPE OF WRITE ; 0=NORMAL WRITE ; 1=WRITE TO A DIRECTORY SECTOR ; 2=1ST WRITE TO A SECTOR IN AN UNALLOCATED BLOCK ; EXIT: (AL)=ERROR STATUS ; 0=NO ERROR , 1=ER=ROR ; USES: ALL ; WRITEE: PUSH ES MOV BWRFLG,CL ;SAVE TYPE OF WRITE MOV PREREAD,1 ;DO PREREAD CALL SETUP ;CALL R/W COMMON SETUP ROUTINE CMP BUFERR[BX],0 ;Q. ERROR DURING SETUP JNE WRITEE5 ; BR IF YES ; HOST BUFFER CONTAINS TRACK FOR REQUESTED CP/M SECTOR. ; COPY THE SECTOR FROM USER BUFFER TO HOST BUFFER. PUSH DS LES DI,DWORD PTR BUFBUF[BX] ;COMPUTE START OF REQ CP/M SECTOR ADD DI,AX ; IN HOST BUFFER LDS SI,DWORD PTR DMAPTR ;GET DMA POINTER CLD REP MOVSW ;MOVE DATA FROM USER TO HOST BUFFER POP DS ; MARK PHYSICAL SECTOR AND HOST WRITE BUFFER AS DIRTY CALL CPSEC ;MARK WHICH HOST WRITE BUFFER MOV DI,BUFSECF[BX] ADD DI,PHYSEC MOV BYTE PTR [DI],1 ; PHYSICAL SECTOR IS DIRTY MOV BUFWRF[BX],1 ;INDICATE HOST BUFFER IS DIRTY ; CHECK FOR ABORT IF ERROR ON PREREAD CALL CPSEC OR DSKOP,DSKOPR CALL ABTIGN AND DSKOP,NOT DSKOPR CMP BUFERR[BX],0 JNE WRITEE5 ; IF TYPE OF WRITE IS A DIRECTORY WRITE, ; THEN FLUSH ALL HOST BUFFERS FOR REQUESTED DRIVE. CMP BWRFLG,BWRDIR ;CHECK TYPE OF WRITE JNE WRITEE5 ; BR IF NOT DIRECTORY WRITE CALL FLUSHD ;FLUSH BUFFERS JMPS WRITEE6 ; WRITEE5: MOV AL,BUFERR[BX] ;INDICATE ERROR STATUS WRITEE6: POP ES RET ;** CHECK LIST DEVICE STATUS ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=STATUS ; 0=NOT READY , 0FFH=READY ; USES: ALL ; LSTSTE: MOV AL,IOBYTE ;GET IOBYTE VALUE MOV CL,5 ;ADJUST VALUE SHR AL,CL CALL GETCIO ;GET APPROPRIATE CIO TABLE ENTRY DW SERATBL DW CRTTBL DW PPRTTBL DW SERBTBL CALL OSCIO ;CALL CIO HANDLER RET ;** SECTOR TRANSLATE ENTRY ; ; ENTRY: (CX)=LOGICAL SECTOR NUMBER (IN RANGE 0 TO SPT-1) ; (DX)=ADDRESS OF SECTOR TABLE ; EXIT: (BX)=TRANSLATED CP/M SECTOR NUMBER (IN RANGE 1 TO SPT) ; USES: ALL ; SECTRNE: MOV BX,CX TEST DX,DX JZ SECTRNE1 ADD BX,DX MOV BL,[BX] XOR BH,BH JMPS SECTRNE2 SECTRNE1: INC BX SECTRNE2: RET ;** SET DMA SEGMENT ADDRESS ; ; ENTRY: (CX)=SEGMENT BASE FOR DMA READ OR WRITE OPERATIONS ; EXIT: NONE ; USES: NONE ; SDMABE: MOV DMASEG,CX ;SAVE FOR LATER RET ;** GET THE OFFSET OF THE MEMORY REGION TABLE ; ; ENTRY: NONE ; EXIT: (BX)=OFFSET OF THE MEMORY REGION TABLE ; USES: BX ; GETMRTE: LEA BX,MSEGTBL RET ;** GET THE I/O MAPPING BYTE ; ; ENTRY: NONE ; EXIT: (AL)=VALUE ; USES: AL ; GETIOBE: MOV AL,IOBYTE RET ;** SET THE I/O MAPPYING BYTE ; ; ENTRY: (CL)=VALUE ; EXIT: NONE ; USES: NONE ; SETIOBE: MOV IOBYTE,CL RET ;** FORMAT - FORMAT ENTRY ; ; ENTRY: (CL)=VERIFY FLAG (0=NO , 1=YES) ; EXIT: (AL)=STATUS BYTE ; USES: ALL ; FORMATE: PUSH ES MOV FVFLG,CL ;SAVE VERIFY FLAG CALL CLRBUFD ;CLEAR HOST BUFFERS FOR THIS DRIVE MOV PREREAD,0 ;DON'T PREREAD CALL SETUP ;GET A BUFFER TO USE MOV AL,0FFH CMP BUFERR[BX],0 ;Q. ERROR DURING SETUP JNE FORMATE1 ; BR IF YES MOV AL,DDFMT ;CALL DEVICE DRIVER TO DO FORMAT CALL DRVR XOR AL,AL ;ASSUME NO ERROR STATUS CMP BUFERR[BX],0 ;Q. ERROR JE FORMATE1 ; BR IF NOT MOV AL,ERRTYP ;GET ERROR STATUS BYTE FORMATE1: PUSH AX CALL CLRBUFD ;GIVE BACK BUFFER POP AX POP ES RET ;** READ TRACK ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; 0=NO ERROR , 1=ERROR ; USES: ALL ; RDTRKE: PUSH ES MOV PREREAD,0 ;INDICATE NO PREREAD CALL SETUP ;CALL R/W COMMON SETUP ROUTINE CMP BUFERR[BX],0 ;Q. ERROR DURING SETUP JNE RDTRKE1 ; BR IF YES MOV AL,DDRDT ;FORCE PHYSICAL READ OF TRACK CALL DRVR ; HOST BUFFER CONTAINS REQUESTED CP/M TRACK. ; COPY IT TO USER BUFFER. MOV SI,BUFDPE[BX] ;COMPUTE # BYTES TO COPY MOV SI,DPEDPB[SI] MOV AX,DPBSPT[SI] MOV CL,7 SHL AX,CL MOV CX,AX PUSH DS LES DI,DWORD PTR DMAPTR ;GET DMA POINTER LDS SI,DWORD PTR BUFBUF[BX] ;GET START OF HOST BUFFER CLD REP MOVSB ;MOVE DATA FROM HOST TO USER BUFFER POP DS ; RDTRKE1: MOV AL,BUFERR[BX] ;INDICATE ERROR STATUS POP ES RET ;** WRITE TRACK ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; 0=NO ERROR , 1=ERROR ; USES: ALL ; WRTRKE: PUSH ES MOV PREREAD,0 ;INDICATE NO PREREAD CALL SETUP ;CALL R/W COMMON SETUP ROUTINE CMP BUFERR[BX],0 ;Q. ERROR DURING SETUP JNE WRTRKE3 ; BR IF YES ; COPY THE TRACK FROM USER BUFFER TO HOST BUFFER MOV SI,BUFDPE[BX] ;COMPUTE # BYTES MOV SI,DPEDPB[SI] MOV AX,DPBSPT[SI] PUSH AX MOV CL,7 SHL AX,CL MOV CX,AX PUSH DS LES DI,DWORD PTR BUFBUF[BX] ;GET START OF HOST BUFFER LDS SI,DWORD PTR DMAPTR ;GET DMA POINTER CLD REP MOVSB ;MOVE DATA FROM USER TO HOST BUFFER POP DS ; MARK PHYSICAL SECTORS AND HOST BUFFER AS DIRTY POP AX ;COMPUTE # PHYSICAL SECTORS PER TRACK MOV DI,BUFDPE[BX] CMP REQTRK,0 JNE WRTRKE1 TEST DPEFLAG[DI],DPET0SD JZ WRTRKE1 MOV AL,26 JMPS WRTRKE2 WRTRKE1: DIV DPERPS[DI] WRTRKE2: CBW MOV CX,AX MOV AL,1 ;SET DIRTY SECTOR FLAGS MOV DI,BUFSECF[BX] CLD CALL EXDSES REP STOSB CALL EXDSES MOV BUFWRF[BX],1 ;INDICATE HOST BUFFER IS DIRTY ; CALL FLUSH ;FLUSH BUFFER WRTRKE3: MOV AL,BUFERR[BX] ;INDICATE ERROR STATUS POP ES RET ;** WRITE PROTECT CHECK ; ; ENTRY: NONE ; EXIT: (AL)=STATUS < (0=R/W , 1=R/O) ; USES: ALL ; WPCE: PUSH ES LEA BX,DMYHDR ;USE DUMMY BUFFER HEADER MOV AL,REQDRV MOV BUFDRV[BX],AL MOV AL,PHYDRV MOV BUFPDRV[BX],AL MOV AX,PHYDPE MOV BUFDPE[BX],AX MOV AL,DDWPC ;CALL DEVICE DRIVER TO DO CHECK CALL DRVR MOV AL,BUFERR[BX] ;GET RETURN VALUE POP ES RET ;** GET BIOS TABLES ; ; ENTRY: NONE ; EXIT: (BX)=OFFSET ; USES: BX ; GETBTE: LEA BX,BIOSTBL RET EJECT ;*** DISK BUFFER HANDLING ROUTINES ; ;** SETUP -- COMMON R/W ROUTINE SETUP CODE ; ; ENTRY: 'REQDRV'=REQUESTED DRIVE # ; 'PHYDPE'=ADDRESS OF DPE FOR REQUESTED DRIVE ; 'REQTRK'=REQUESTED TRACK # ; EXIT: HOST BUFFER CONTAINS REQUESTED TRACK ; (BX)=ADDRESS OF BUFFER HEADER INFO ; (AX)=DISPLACEMENT OF REQUESTED CP/M SECTOR INTO HOST BUFFER ; (CX)=128/2=64 ; DIRECTION FLAG CLEARED TO FORWARD DIRECTION ; USES: AX,CX,DI ; ; *** NOTE *** ; ; IF A 1ST TIME SELECT OPERATION IS IN PROGRESS, THEN NO PHYSICAL ; READ IS DONE. IN THIS CASE, THIS ROUTINE ONLY SERVES TO ; AQUIRE A FREE BUFFER TO BE USED BY THE DEVICE SELECTION ; ROUTINES FOR THEIR OWN PURPOSES. ; SETUP: CALL FNDBUF ;Q. REQUESTED TRACK IN ANY HOST BUFFERS MOV BUFERR[BX],0 ;CLEAR ERROR FLAG JNC SETUP1 ; BR IF YES CALL FLUSH ;FLUSH LEAST RECENTLY USED HOST BUFFER CMP BUFERR[BX],0 ;Q. ERROR DURING FLUSH JNE SETUP2 ; BR IF YES ; SET BUFFER HEADER INFO FOR REQUESTED TRACK MOV AL,REQDRV ;DRIVE # MOV BUFDRV[BX],AL MOV AL,PHYDRV ;MAPPED DRIVE # (PHYSICAL TABLE #) MOV BUFPDRV[BX],AL MOV AX,PHYDPE ;ADDRESS OF DPE MOV BUFDPE[BX],AX MOV AX,REQTRK ;TRACK # MOV BUFTRK[BX],AX ; CLEAR ERROR SECTOR FLAGS XOR AL,AL MOV DI,BUFERRF[BX] MOV CX,ERRFLGL CLD CALL EXDSES REP STOSB CALL EXDSES ; CMP PREREAD,0 ;Q. SHOULD I DO PREREAD JE SETUP2 ; BR IF NO MOV AL,DDRDT ;DO PHYSICAL READ AND FILL HOST BUFFER CALL DRVR ; REQUESTED TRACK IS IN A HOST BUFFER. ; SET MOVE VALUES. SETUP1: MOV AX,REQSEC ;CALCULATE DISPLACEMENT MOV CL,7 SHL AX,CL MOV CX,64 ;WORD COUNT MOV BUFERR[BX],0 ;INSURE ERROR FLAG IS CLEARED SETUP2: RET ;** FNDBUF -- FIND HOST BUFFER TO USE ; ; ENTRY: 'REQDRV'=DRIVE # ; 'REQTRK'=TRACK # ; EXIT: PSW/C=STATUS ; 0=REQUESTED TRACK IS IN HOST BUFFER TO BE USED. ; HEADER INFO FOR BUFFER IS ON TOP OF BUFFER STACK ; 1=NOT FOUND. ; HEADER INFO FOR THE LEAST RECENTLY USED BUFFER ; IS PLACED ON TOP OF BUFFER STACK SO IT CAN BE ; FLUSHED AND THEN USED ; USES: AL,BX,DX ; FNDBUF: MOV AL,REQDRV ;REQUESTED DRIVE # MOV DX,REQTRK ;REQUESTED TRACK # MOV BX,FSTBUF ;INIT POINTER FNDBUF1: TEST BX,BX ;Q. NO MORE BUFFER HEADERS JZ FNDBUF3 ; BR IF NOT CMP AL,BUFDRV[BX] ;Q. MATCH ON REQUESTED DRIVE JNE FNDBUF2 ; BR IF NOT CMP DX,BUFTRK[BX] ;Q. MATCH ON REQUEST ED TRACK JE FNDBUF4 ; BR IF YES FNDBUF2: MOV BX,BUFFWD[BX] ;FOLLOW CHAIN TO NEXT INFO ELEMENT JMPS FNDBUF1 FNDBUF3: MOV BX,LSTBUF ;POINT TO LAST ELEMENT STC ;INDICATE NOT FOUND FNDBUF4: PUSHF ;SAVE FOUND STATUS CALL PSHBUF ;PLACE BUFFER TO BE USED ON TOP OF STACK POPF ;RESTORE FOUND STATUS RET ;** INBUF -- INITIALIZE BUFFER HEADERS ; ; ENTRY: NONE ; EXIT: NONE ; USES: BX,CX,SI,DI ; INBUF: MOV FSTBUF,0 ;INIT 1ST ELEMENT POINTER MOV LSTBUF,0 ;INIT LAST ELEMENT POINTER ; DETERMINE NUMBER OF BUFFERS TO PROVIDE BASED ON AMOUNT OF MEMORY MOV CX,1 ;1 BUFFER CMP TOPMEM,1000H ;Q. <= 64K JBE INBUF0 ; BR IF YES MOV CX,4 CMP TOPMEM,3000H ;Q. 64K < X <= 192K JBE INBUF0 ; BR IF YES MOV CX,BUFMCNT ;MAX # BUFFERS INBUF0: MOV BUFCNT,CX ;SAVE BUFFER COUNT ; ATTEMPT TO PROVIDE N BUFFERS LEA BX,HEADER ;START OF HEADER AREA LEA SI,SECFLG ;START OF DIRTY SECTOR FLAG AREA LEA DX,ERRFLG ;START OF SECTOR ERROR FLAG AREA INBUF1: MOV AX,BUFSIZ ;GET MEMORY FOR BUFFER CALL GETMEM JC INBUF3 ; BR IF NOT AVAILABLE MOV BUFBUFO[BX],0 ;INIT OFFSET OF BUFFER MOV BUFBUFS[BX],AX ;INIT SEGMENT OF BUFFER MOV BUFSECF[BX],SI ;INIT ADDRESS OF DIRTY SECTOR FLAG AREA MOV BUFERRF[BX],DX ;INIT ADDRESS OF SECTOR ERROR FLAG AREA PUSH BX PUSH CX PUSH DX PUSH SI PUSH BX MOV DI,0 ;INSERT HEADER AT END CALL INSBUF POP BX CALL CLRBUF ;CLEAR BUFFER HEADER POP SI POP DX POP CX POP BX ADD BX,BUFHDRL ;BUMP POINTERS ADD SI,SECFLGL ADD DX,ERRFLGL LOOP INBUF1 ;LOOP FOR # OF BUFFERS INBUF2: SUB BUFCNT,CX ;UPDATE ACTUAL # BUFFERS PROVIDED RET ; OUT OF MEMORY FOR BUFFERS. ERROR IF AT LEAST 1 BUFFER COULD ; NOT BE PROVIDED. INBUF3: CMP CX,BUFCNT ;Q. COUNT = REQUEST JNE INBUF2 ; BR IF NOT -- ABLE TO GET AT LEAST 1 LEA SI,BUFMSG CALL PMSG JMP SYSHLT ;** CLRBUFA - CLEAR ALL HOST BUFFER HEADERS ; ; ENTRY: NONE ; EXIT: NONE ; USES: BX ; CLRBUFA: MOV BX,FSTBUF ;GET POINTER TO FIRST HEADER IN CHAIN CLRBUFA1: TEST BX,BX ;Q. AT END OF CHAIN JZ CLRBUFA2 ; BR IF YES CALL CLRBUF ;CLEAR THIS BUFFER HEADER MOV BX,BUFFWD[BX] ;CHAIN TO NEXT HEADER JMPS CLRBUFA1 CLRBUFA2: RET ;** CLRBUFD - CLEAR ALL HOST BUFFER HEADERS FOR REQUESTED DRIVE ; ; ENTRY: 'REQDRV'=REQUESTED DRIVE # ; EXIT: NONE ; USES: AX,BX ; CLRBUFD: PUSH ES MOV BX,FSTBUF ;POINT TO 1ST HEADER ELEMENT CLRBUFD1: TEST BX,BX ;Q. ANY MORE BUFFERS JZ CLRBUFD3 ; BR IF NOT MOV AL,REQDRV ;Q. BUFFER FOR REQUESTED DRIVE CMP AL,BUFDRV[BX] JE CLRBUFD2 ; BR IF YES MOV BX,BUFFWD[BX] ;SKIP TO NEXT ENTRY JMPS CLRBUFD1 CLRBUFD2: CALL CLRBUF ;CLEAR BUFFER MOV AX,BUFFWD[BX] ;REMEMBER WHO SHOULD BE NEXT PUSH AX CALL POPBUF ;POP BUFFER STACK POP BX ;GET NEXT ENTRY JMPS CLRBUFD1 CLRBUFD3: POP ES RET ;** CHKDBD -- CHECK FOR ANY DIRTY BUFFERS FOR REQUESTED DRIVE ; ; ENTRY: 'REQDRV'=REQUESTED DRIVE # ; EXIT: (AL)=STATUS 0=NO DIRTY BUFFERS , 1=DIRTY BUFFER(S) ; USES: AX,BX ; CHKDBD: XOR AH,AH ;ZERO WORK REG MOV AL,REQDRV ;GET REQUESTED DRIVE # MOV BX,FSTBUF ;START OF BUFFER HEADERS CHKDBD1: TEST BX,BX ;Q. ANY MORE BUFFERS JZ CHKDBD3 ; BR IF NOT CMP AL,BUFDRV[BX] ;Q. BUFFER FOR REQUESTED DRIVE JNE CHKDBD2 ; BR IF NOT OR AH,BUFWRF[BX] ;ACCUMULATE DIRTY FLAGS CHKDBD2: MOV BX,BUFFWD[BX] ;SKIP TO NEXT ENTRY JMPS CHKDBD1 CHKDBD3: MOV AL,AH ;MOVE RESULT TO (AL) RET ;** FLUSHD -- FLUSH ALL BUFFERS FOR REQUESTED DRIVE ; ; ENTRY: 'REQDRV'=REQUESTED DRIVE # ; EXIT: (AL)=ERROR STATUS (0=OK , 1=ABORT) ; USES: AL,BX ; FLUSHD: MOV FLDERR,0 ;CLEAR ERROR FLAG MOV BX,FSTBUF ;START OF BUFFER HEADERS FLUSHD1: TEST BX,BX ;Q. ANY MORE BUFFERS JZ FLUSHD3 ; BR IF NOT MOV AL,REQDRV ;Q. BUFFER FOR REQUESTED DRIVE CMP AL,BUFDRV[BX] JNE FLUSHD2 ; BR IF NOT MOV AL,FLDERR ;PROPAGATE ABORT STATUS OR BUFERR[BX],AL CALL FLUSH ;FLUSH BUFFER MOV AL,BUFERR[BX] ;ACCUMULATE ERROR STATUS OR FLDERR,AL FLUSHD2: MOV BX,BUFFWD[BX] ;FOLLOW CHAIN TO NEXT ELEMENT JMPS FLUSHD1 FLUSHD3: MOV AL,FLDERR ;GET ERROR STATUS RET ;* CLRBUF -- CLEAR BUFFER HEADER ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: NONE ; USES: AL,CX,SI,DI ; ; *** NOTE *** ; ; IF A BUFFER WAS NOT FLUSHED BEFORE BEING CLEARED AND ; IF IT WAS DIRTY, THEN THE DATA IS LOST. ; CLRBUF: MOV BUFDRV[BX],-1 ;CLEAR DRIVE # MOV BUFWRF[BX],0 ;CLEAR DIRTY BUFFER FLAG XOR AL,AL ;CLEAR DIRTY SECTOR FLAGS MOV DI,BUFSECF[BX] MOV CX,SECFLGL CLD CALL EXDSES REP STOSB CALL EXDSES RET ;* FLUSH -- FLUSH BUFFER WHOSE HEADER INFO IS ON TOP OF THE STACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: NONE ; USES: NONE ; FLUSH: TEST BUFWRF[BX],1 ;CHECK IF HOST BUFFER IS DIRTY JZ FLUSH1 ; BR IF NOT MOV AL,DDWRT ;GO WRITE TRACK CALL DRVR MOV BUFWRF[BX],0 ;INDICATE HOST WRITE BUFFER IS CLEAN FLUSH1: RET ;* PSHBUF -- PUSH DOWN BUFFER HEADER INFO STACK AND PLACE COPY ; OF HEADER INFO OF BUFFER TO BE USED ON TOP OF STACK. ; ; ENTRY: (BX)=ADDRESS OF HEADER INFO FOR HOST BUFFER TO BE USED ; EXIT: NONE ; USES: DI ; PSHBUF: CMP BX,FSTBUF ;Q. ALREADY ON TOP OF STACK JE PSHBUF1 ; BR IF YES CALL DELBUF ;REMOVE FROM STACK MOV DI,FSTBUF ;REINSERT ON TOP OF STACK CALL INSBUF PSHBUF1: RET ;* POPBUF -- POP UP BUFFER HEADER INFO STACK AND COPY ; HEADER INFO FOR BUFFER USED TO BOTTOM OF STACK. ; ; ENTRY: (BX)=ADDRESS OF HEADER INFO FOR HOST BUFFER TO BE USED ; EXIT: NONE ; USES: DI ; POPBUF: CMP BX,LSTBUF ;Q. ALREADY BOTTOM OF STACK JE POPBUF1 ; BR IF YES CALL DELBUF ;REMOVE FROM CURRENT POSITION MOV DI,0 ;REINSERT AT BOTTOM OF STACK CALL INSBUF POPBUF1: RET ;* DELBUF -- DELETE ELEMENT FROM BUFFER STACK ; ; ENTRY: (BX)=POINTER TO ELEMENT TO BE DELETED ; EXIT: NONE ; USES: SI,DI ; DELBUF: MOV DI,BUFFWD[BX] ;GET POINTER TO NEXT ELEMENT MOV SI,BUFBAK[BX] ;GET POINTER TO PREVIOUS ELEMENT TEST SI,SI ;Q. FIRST ELEMENT JNZ DELBUF1 ; BR IF NOT MOV FSTBUF,DI ;SET NEXT ELEMENT AS FIRST ELEMENT JMPS DELBUF2 DELBUF1: MOV BUFFWD[SI],DI ;CHAIN PREVIOUS ELEMENT TO NEXT ELEMENT DELBUF2: TEST DI,DI ;Q. LAST ELEMENT JNZ DELBUF3 ; BR IF NOT MOV LSTBUF,SI ;SET PREVIOUS ELEMENT AS LAST ELEMENT JMPS DELBUF4 DELBUF3: MOV BUFBAK[DI],SI ;CHAIN NEXT ELEMENT TO PREVIOUS ELEMENT DELBUF4: RET ;* INSBUF -- INSERT BUFFER HEADER INFO INTO STACK ; ; ENTRY: (BX)=ADDRESS OF ELEMENT TO BE INSERTED ; (DI)=ADDRESS OF ELEMENT TO BE INSERTED IN FRONT OF ; EXIT: NONE ; USES: SI ; ; *** NOTE *** ; ; IF (DI)=0 THEN INSERTION IS DONE AFTER LAST ELEMENT ; INSBUF: TEST DI,DI ;Q. INSERT AT END JNZ INSBUF3 ; BR IF NO ; INSERT AFTER LAST ELEMENT MOV SI,LSTBUF ;GET POINTER TO LAST ELEMENT TEST SI,SI ;Q. ANY ELEMENTS JNZ INSBUF1 ; BR IF YES MOV FSTBUF,BX ;SET ELEMENT AS FIRST ELEMENT JMPS INSBUF2 INSBUF1: MOV BUFFWD[SI],BX ;CHAIN LAST ELEMENT TO ELEMENT INSBUF2: MOV BUFFWD[BX],0 ;SET ELEMENT'S FORWARD POINTER MOV BUFBAK[BX],SI ;CHAIN ELEMENT TO LAST ELEMENT MOV LSTBUF,BX ;SET ELEMENT AS LAST ELEMENT RET ; INSERT IN FRONT OF ELEMENT POINTED TO BY (DI) INSBUF3: MOV SI,BUFBAK[DI] ;GET POINTER TO PREVIOUS ELEMENT TEST SI,SI ;Q. ANY PREVIOUS ELEMENT JNZ INSBUF4 ; BR IF YES MOV FSTBUF,BX ;SET ELEMENT AS FIRST ELEMENT JMPS INSBUF5 INSBUF4: MOV BUFFWD[SI],BX ;CHAIN PREVIOUS ELEMENT TO ELEMENT INSBUF5: MOV BUFBAK[BX],SI ;CHAIN ELEMENT TO PREVIOUS ELEMENT MOV BUFBAK[DI],BX ;CHAIN NEXT ELEMENT TO ELEMENT MOV BUFFWD[BX],DI ;CHAIN ELEMENT TO NEXT ELEMENT RET EJECT ;** DRVR - DISK DRIVER DISPATCHER ; ; ENTRY: (AL)=ENTRY JUMP VECTOR OFFSET ; (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: NONE ; USES: AX,CL,SI,DI ; DRVR: PUSH AX MOV LSIO,0 ;CLEAR LOGICAL SECTOR I/ O FLAG ;* INSURE CORRECT DISK IS INSERTED IN REQUESTED DRIVE MOV SI,BUFDPE[BX] ;GET ADDRESS OF REQUESTED DRIVE'S DPE MOV AL,DPEFLAG[SI] ;NOT ALL DEVICES ARE PERMITTED AND AL,DPETYPE ; IMAGINARY DRIVES CMP AL,DPEZ217 JNE DRVR0 ; BR IF NOT Z217 MOV LSIO,1 ;INDICATE LOGICAL I/O DEVICE JMPS DRVR5 DRVR0: TEST DPEFLG2[SI],DPEIMG ;Q. IMAGINARY DRIVE JZ DRVR1 ; BR IF NOT MOV AL,DPELUN[SI] ;POINT TO CORRESPONDING REAL DRIVE AND AL,DPEREAL MOV AH,DPEL MUL AH ADD AX,OFFSET DPEBASE MOV SI,AX DRVR1: MOV AL,DPELUN[SI] ;GET LOGICAL/MOUNTED VALUE MOV AH,AL ;SAVE IT AND AL,DPEMNT ;MASK FOR MOUNTED VALUE CMP AL,BUFPDRV[BX] ;Q. MOUNTED EQUAL REQUESTED JE DRVR5 ; BR IF YES AND AH,DPELOG ;UPDATE MOUNTED VALUE OR AH,BUFPDRV[BX] ; TO REFLECT WHICH DISK IS MOUNTED MOV DPELUN[SI],AH ; IN REAL UNIT ; PRINT MESSAGE AND REQUEST THAT DISK BE INSERTED INTO DRIVE MOV AL,BUFDRV[BX] ;PLACE REQUESTED DRIVE NAME INTO MSG ADD AL,'A' MOV MNMSGA,AL MOV CL,4 ;PLACE REAL DRIVE NAME INTO MESSAGE SHR AH,CL ADD AH,'A' MOV MNMSGB,AH PUSH BX LEA SI,MNMSG ;PRINT MESSAGE CALL PMSG DRVR3: CALL GETCHR ;WAIT FOR CMP AL,CR JE DRVR4 MOV CL,BELL CALL CONOUTE JMPS DRVR3 DRVR4: LEA SI,CRLF CALL PMSG POP BX MOV AL,DDMNT ;CALL DEVICE DRIVER TO MOUNT DISK CALL DRVR6 ;* DISPATCH TO DEVICE DRIVER DRVR5: POP AX ;RESTORE ENTRY JUMP VECTOR OFFSET DRVR6: MOV AH,0 MOV DI,AX MOV SI,BUFDPE[BX] ;FETCH DEVICE TYPE MOV AL,DPEFLAG[SI] MOV CL,5 SHR AL,CL CBW ;ADJUST FOR DISPATCH TABLE ENTRY LENGTH SHL AX,1 MOV SI,AX MOV SI,DRVRTBL[SI] ;GET OFFSET OF START OF DEVICE DRIVER CMP SI,0 ;Q. DUMMY DRIVER JE DRVR7 ; BR IF YES ADD SI,DI ;ADD ENTRY JUMP VECTOR OFFSET JMP SI ;GOTO DEVICE DRIVER DRVR7: RET EJECT INCLUDE Z207DRVR.LIB EJECT INCLUDE Z217DRVR.LIB EJECT INCLUDE TIMEDRVR.LIB EJECT ;*** GENERAL PURPOSE CHARACTER I/O HANDLER ; ;* GETCIO - GET APPROPRIATE CIO TABLE ENTRY ; ; ENTRY: (AL)='IOBYTE' SHIFTED SO BITS 1-2 CONTAIN THE PERTINENT VALUE ; ((SP))=START OF ADDRESS OFFSET TABLE ; EXIT: (BX)=ADDRESS OF CIO TABLE ENTRY ; USES: AX,BX ; ; *** NOTE *** ; THE TABLE CONSISTS OF 4 DW STATEMENTS, WHICH EQUALS 8 BYTES ; GETCIO: AND AX,06H ;MASK FOR ONLY BITS 1-2 POP BX ;GET START OF TABLE ADD AX,BX ;MOVE POINTER TO APPROPRIATE ENTRY ADD BX,8 ;MODIFY RETURN ADDRESS TO SKIP PUSH BX ; AROUND TABLE MOV BX,AX MOV BX,CS: WORD PTR [BX] ;GET VALUE IN TABLE RET ;* CLRCIO - CLEAR CIO TABLE FLAGS/VALUES ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: NONE ; USES: NONE ; CLRCIO: AND CIOF2[BX],NOT (CIOW4A+CIOW4D) MOV CIOECTR[BX],0 MOV CIONCTR[BX],0 RET ;* ISCIO - INPUT STATUS ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=STATUS ; 0=NO CHARACTER AVAILBLE , 0FFH=CHARACTER AVAILBLE ; USES: AL ; ISCIO: CALL CIOIS[BX] ;INPUT STATUS BYTE FROM DEVICE AND AL,CIOIM[BX] ;USE INPUT READY MASK XOR AL,CIOIPM[BX] ;ADJUST FOR POLARITY CMP AL,CIOIM[BX] ;CHECK IF READY MOV AL,0FFH ; ASSUME READY JE ISCIO1 ; BR IF READY XOR AL,AL ; OTHERWISE SHOW NOT READY ISCIO1: RET ;* IDCIO - INPUT DATA ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=CHARACTER READ ; USES: AL ; IDCIO: CALL ISCIO ;WAIT FOR CHARACTER AVAILABLE TEST AL,AL JZ IDCIO CALL CIOID[BX] ;INPUT DATA TEST CIOF1[BX],CIOSPI ;Q. STRIP PARITY JZ IDCIO1 ; BR IF NOT AND AL,07FH ; OTHERWISE STRIP PARITY IDCIO1: TEST CIOF1[BX],CIOMLI ;CHECK IF I SHOULD MAP LOWER CASE JZ IDCIO2 ; BR IF NOT CALL UPC ; OTHERWISE DO MAPPING IDCIO2: RET ;* OSCIO - OUTPUT STATUS ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=STATUS ; 0=NOT READY , 0FFH=READY ; USES: AL ; OSCIO: CALL CIOOS[BX] ;INPUT STATUS BYTE FROM DEVICE AND AL,CIOOM[BX] ;USE OUTPUT READY MASK XOR AL,CIOOPM[BX] ;ADJUST FOR POLARITY CMP AL,CIOOM[BX] ;CHECK I F READY ; JNE OSCIO8 ; BR IF BUSY JE $+5 JMP OSCIO8 ; HANDLE / PROTOCOL OSCIO2: TEST CIOF1[BX],CIOEAH ;Q. USING / HANDSHAHKING JZ OSCIO3 ; BR IF NOT TEST CIOF2[BX],CIOW4A ;Q. WAITING FOR JNZ OSCIO2A ; BR IF YES MOV AL,CIOECTR[BX] ;Q. TIME TO SEND CMP AL,CIOECNT[BX] JB OSCIO4 ; BR IF NOT MOV CIOECTR[BX],0 ;REINITIALIZE COUNTER MOV AL,ETX ;SEND CALL CIOOD[BX] OR CIOF2[BX],CIOW4A ;SHOW WAITING FOR JMP OSCIO8 ;JUMP TO BUSY EXIT OSCIO2A: CALL ISCIO ;CHECK INPUT STATUS TEST AL,AL ;Q. CHARACTER AVAILABLE JZ OSCIO8 ; BR IF NOT CALL CIOID[BX] ;INPUT CHARACTER AND AL,07FH ;STRIP PARITY BIT CMP AL,ACK ;Q. JNE OSCIO8 ; BR IF NOT AND CIOF2[BX],0FFH-CIOW4A ;SHOW NOT WAITING FOR JMPS OSCIO4 ; HANDLE / PROTOCOL OSCIO3: TEST CIOF1[BX],CIODCH ;Q. USING / HANDSHAKING JZ OSCIO4 ; BR IF NOT CALL ISCIO ;INPUT STATUS TEST AL,AL ;Q. CHARACTER AVAILABLE JZ OSCIO3C ; BR IF NOT CALL CIOID[BX] ;INPUT CHARACTER AND AL,07FH ;STRIP PARITY BIT OSCIO3A: CMP AL,DC1 ;Q. JNE OSCIO3B ; BR IF NOT AND CIOF2[BX],0FFH-CIOW4D ;SHOW NOT WAITING FOR JMPS OSCIO4 OSCIO3B: CMP AL,DC3 ;Q. JNE OSCIO3C ; BR IF NOT OR CIOF2[BX],CIOW4D ;SHOW WAITING FOR JMPS OSCIO8 OSCIO3C: TEST CIOF2[BX],CIOW4D ;Q. WAITING FOR JNZ OSCIO8 ; BR IF YES ; HANDLE SENDING NULLS OSCIO4: CMP CIONCTR[BX],0 ;Q. ANY NULLS LEFT TO SEND JE OSCIO9 ; BR IF NOT DEC CIONCTR[BX] ;DECREMENT NULL COUNTER MOV AL,NULL ;SEND ANOTHER NULL CALL CIOOD[BX] ; SHOW AS BUSY OSCIO8: XOR AL,AL RET ; SHOW AS READY OSCIO9: MOV AL,0FFH RET ;* ODCIO - OUTPUT DATA ; ; ENTRY: (CL)=CHARACTER ; (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: NONE ; USES: AL ; ; *** NOTE *** ; ; THE DEVICE OUTPUT ROUTINE MUST NOT DESTROY REGISTER (CL) OR (BX). ; ODCIO: TEST CIOF1[BX],CIOFO ;Q. FAST I/O JZ ODCIO0 ; BR IF NOT MOV AL,CL JMP CIOOD[BX] ;DO OUTPUT ODCIO0: CALL OSCIO ;WAIT UNTIL READY TEST AL,AL JZ ODCIO0 MOV AL,CL TEST CIOF1[BX],CIOSPO ;Q. STRIP PARITY JZ ODCIO1 ; BR IF NOT AND AL,07FH ODCIO1: TEST CIOF1[BX],CIOMLO ;Q. MAP LOWER CASE ON OUTPUT JZ ODCIO2 ; BR IF NOT CALL UPC ; OTHERWISE DO MAPPING ODCIO2: CALL CIOOD[BX] ;OUTPUT CHARACTER CMP CL,CIONCHR[BX] ;Q. SHOULD I SEND NULLS JNE ODCIO3 ; BR IF NOT MOV AL,CIONCNT[BX] ;GET NUMBER OF NULLS TO BE SENT MOV CIONCTR[BX],AL ;PLACE IN NULL COUNTER ODCIO3: INC CIOECTR[BX] ;COUNT CHARACTER CMP CL,ESC ;Q. JNE ODCIO4 ; BR IF NOT MOV AL,CIOECNT[BX] ; IF YES - THEN INSURE SUB AL,3 ; ETX/ACK HANDSHAKING IS DELAYED CMP CIOECTR[BX],AL JB ODCIO4 MOV CIOECTR[BX],AL ODCIO4: RET EJECT ;*** DEVICE DRIVERS ; ;** CRT: (KEYBOARD/DISPLAY) ; ;* INCRT - INITIALIZATION ; ; ENTRY: NONE ; EXIT: NONE ; USES: AX,BX ; INCRT: PUSHF ;INSURE INTERRUPTS ARE DISABLED CLI ; DURING INIT LEA BX,CRTTBL ;GET ADDRSS OF CIO TABLE ENTRY CALL CLRCIO ;CLEAR CIO TABLE FLAGS MOV CIOIN[BX],OFFSET INCRT ;ADDRESS OF INIT ROUTINE MOV CIOIS[BX],OFFSET ISCRT ;ADDRESS OF INPUT INPUT STATUS BYTE MOV CIOID[BX],OFFSET IDCRT ;ADDRESS OF INPUT DATA BYTE MOV CIOOS[BX],OFFSET DUMMY ;ADDRESS OF INPUT OUTPUT STATUS BYTE MOV CIOOD[BX],OFFSET ODCRT ;ADDRESS OF OUTPUT DATA BYTE CALL FLCRT ;FLUSH TYPEAHEAD BUFFER XOR AX,AX ;INITIALIZE KEYBOARD HANDLER TO MOV ES,AX ; USE MY QUEUE MOV ES,ES: .MTRDSEG MOV ES:MTRDXMTC,MTRSKBD MOV ES:MTRDXMTC+2,MTRSEG MOV ES:MTRSXMTC,OFFSET PUTKEY MOV ES:MTRSXMTC+2,CS INCRT1: IN AL,ZKEYBDS ;INSURE KEYBOARD INTERRUPTS TEST AL,ZKEYIBF ; ARE ENABLED JNZ INCRT1 MOV AL,ZKEYEI OUT ZKEYBDC,AL POPF ;RESTORE INTERRUPT STATUS RET ;* FLCRT - FLUSH CRT: TYPE AHEAD BUFFER ; ; ENTRY: NONE ; EXIT: NONE ; USES: NONE ; FLCRT: PUSH AX PUSH BX PUSHF ;DISABLE INTERRUPTS CLI FLCRT1: IN  AL,ZKEYBDS ;DISABLE KEYBOARD TEST AL,ZKEYIBF JNZ FLCRT1 MOV AL,ZKEYDK OUT ZKEYBDC,AL FLCRT2: IN AL,ZKEYBDS ;CLEAR FIFO TEST AL,ZKEYIBF JNZ FLCRT2 MOV AL,ZKEYCF OUT ZKEYBDC,AL FLCRT3: IN AL,ZKEYBDS ;CLEAR OUTPUT BUFFER TEST AL,ZKEYIBF JNZ FLCRT3 IN AL,ZKEYBDD CALL FLCRT9 ;FLUSH TYPE AHEAD BUFFER POPF ;RESTORE INTERRUPT STATUS PUSHF ;Q. INTERRUPTS ENABLED POP AX TEST AH,002H JZ FLCRT4 ; BR IF NOT MOV AX,250*250 ;WAIT IN CASE KEY WAS DEPRESSED CALL WDLY ; DURING FLUSH CALL WDLY FLCRT4: MOV AL,ZKEYEK ;RE-ENABLE KEYBOARD OUT ZKEYBDC,AL POP BX POP AX RET FLCRT9: MOV KEYCNT,0 ;INIT BUFFER HANDLING VALUES LEA BX,KEYBUF MOV KEYPUT,BX MOV KEYGET,BX RET ;* ISCRT - INPUT INPUT STATUS BYTE ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=STATUS ; 0=NO DATA AVAILABLE , 0FFH=DATA IN TYPE-AHEAD BUFFER ; USES: AL ; ISCRT: MOV AL,KEYCNT ;GET TYPE-AHEAD CHARACTER COUNT TEST AL,AL ;Q. ANY CHARACTERS AVAILABLE JZ ISCRT1 ; BR IF NOT MOV AL,0FFH ; INDICATE AVAILABLE ISCRT1: RET ;* IDCRT - GET DATA BYTE FROM TYPE-AHEAD BUFFER ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=DATA BYTE ; USES: AL ; IDCRT: CALL ISCRT ;Q. ANY AVAILABLE TEST AL,AL JZ IDCRT2 ; BR IF NOT PUSHF ;DISABLE INTERRUPTS WHILE FETCHING CLI ; CHARACTER PUSH BX MOV BX,KEYGET ;FETCH GET POINTER MOV AL,[BX] ;FETCH CHARACTER DEC KEYCNT ;DECREMENT CHARACTER COUNTER INC BX ;BUMP GET POINTER CMP BX,OFFSET KEYBUF + KEYBUFL ;Q. TIME TO WRAP POINTER JB IDCRT1 ; BR IF NOT LEA BX,KEYBUF ; WRAP POINTER TO BEGINNING IDCRT1: MOV KEYGET,BX ;SAVE UPDATED GET POINTER POP BX POPF IDCRT2: RET ;* ODCRT - OUTPUT DATA ; ; ENTRY: (AL)=CHARACTER ; (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: NONE ; USES: NONE ; ODCRT: PUSH BX MOV MSAVSS,SS ;SET UP LOCAL STACK FOR MONITOR CALL MOV MSAVSP,SP MOV BX,DS MOV SS,BX LEA SP,MSTACK PUSHA CLD CALLFI MTRSCRT,MTRSEG ;CALL ROM MONITOR ROUTINE POPA MOV SS,MSAVSS MOV SP,MSAVSP ;RESTORE (SP) POP BX RET ;* PUTKEY - PUT DATA BYTE INTO TYPE-AHEAD BUFFER ; ; ENTRY: (AL)=CHARACTER ; (CS)=CODE SEGMENT VALUE ; EXIT: NONE ; USES: (AL) ; ; THIS ROUTINE IS CALLED BY THE ROM MONITOR AT INTERRUPT TIME PUTKEY: PUSH BX CMP CS:KEYCNT,KEYBUFL ;Q. BUFFER FULL JB PUTKEY2 ; BR IF NOT PUTKEY1: IN AL,ZKEYBDS ;SEND BEEP TO INDICATE BUFFER FULL TEST AL,ZKEYIBF JNZ PUTKEY1 MOV AL,ZKEYBEP OUT ZKEYBDC,AL JMPS PUTKEY4 PUTKEY2: MOV BX,CS:KEYPUT ;GET PUT POINTER MOV CS:[BX],AL ;PUT CHARACTER INTO BUFFER INC CS:KEYCNT ;BUMP CHARACTER COUNTER INC BX ;BUMP PUT POINTER CMP BX,OFFSET KEYBUF + KEYBUFL ;Q. TIME TO WRAP POINTER JB PUTKEY3 ; BR IF NOT LEA BX,CS:KEYBUF ; WRAP POINTER TO BEGINNING PUTKEY3: MOV CS:KEYPUT,BX ;SAVE UPDATED PUT POINTER PUTKEY4: POP BX RETF ;** SERIAL PORT A DEVICE DRIVER ; ;* INSERA - INITIALIZATION ; ; ENTRY: NONE ; EXIT: NONE ; USES: BX ; INSERA: PUSHF ;INSURE INTERRUPTS ARE DISABLED CLI ; DURING INIT LEA BX,SERATBL ;GET ADDRESS OF CIO ENTRY CALL CLRCIO ;CLEAR CIO TABLE FLAGS MOV CIOIN[BX],OFFSET INSERA ;ADDRESS OF INIT ROUTINE MOV CIOIS[BX],OFFSET IS2661 ;ADDRESS OF INPUT INPUT STATUS ROUTINE MOV CIOID[BX],OFFSET ID2661 ;ADDRESS OF INPUT DATA ROUTINE MOV CIOOS[BX],OFFSET IS2661 ;ADDRESS OF INPUT OUTPUT STATUS ROUTINE MOV CIOOD[BX],OFFSET OD2661 ;ADDRESS OF OUTPUT DATA ROUTINE CALL IN2661 ;CALL DEVICE INIT ROUTINE POPF ;RESTORE INTERRUPT STATUS RET ;** SERIAL PORT B DEVICE DRIVER ; ;* INSERB - INITIALIZATION ; ; ENTRY: NONE ; EXIT: NONE ; USES: BX ; INSERB: PUSHF ;INSURE INTERRUPTS ARE DISABLED CLI ; DURING INIT LEA BX,SERBTBL ;GET ADDRESS OF CIO ENTRY CALL CLRCIO ;CLEAR CIO TABLE FLAGS MOV CIOIN[BX],OFFSET INSERB ;ADDRESS OF INIT ROUTINE MOV CIOIS[BX],OFFSET IS2661 ;ADDRESS OF INPUT INPUT STATUS ROUTINE MOV CIOID[BX],OFFSET ID2661 ;ADDRESS OF INPUT DATA ROUTINE MOV CIOOS[BX],OFFSET IS2661 ;ADDRESS OF INPUT OUTPUT STATUS ROUTINE MOV CIOOD[BX],OFFSET OD2661 ;ADDRESS OF OUTPUT DATA ROUTINE CALL IN2661 ;CALL DEVICE INIT ROUTINE POPF ;RESTORE INTERRUPT STATUS RET ;** 2661 COMMON DEVICE DRIVER ROUTINES ; ;* IS2661 - INPUT INPUT/OUTPUT STATUS BYTE ; ; ENTRY: (BX)=ADDRESS OF CIO ENTRY ; EXIT: (AL)=STATUS BYTE ; USES: AL,DX ; IS2661: XOR DH,DH ;GET STATUS PORT # MOV DL,CIOBP[BX] ADD DX,EPSTAT IN AL,DX ;GET STATUS RET ;* ID2661 - INPUT DATA BYTE ; ; ENTRY: (BX)=ADDRESS OF CIO ENTRY ; EXIT: (AL)=DATA BYTE ; USES: AL,DX ; ID2661: XOR DH,DH ;GET DATA PORT # MOV DL,CIOBP[BX] ADD DX,EPDATA IN AL,DX ;INPUT DATA RET ;* OD2661 - OUTPUT DATA BYTE ; ; ENTRY: (AL)=DATA BYTE ; (BX)=ADDRESS OF CIO ENTRY ; EXIT: NONE ; USES: DX ; OD2661: XOR DH,DH ;GET DATA PORT # MOV DL,CIOBP[BX] ADD DX,EPDATA OUT DX,AL ;OUTPUT DATA RET ;* IN2661 - INITIALIZE ; ; ENTRY: (BX)=ADDRESS OF CIO ENTRY ; EXIT: NONE ; USES: AL,DX ; IN2661: PUSH CX XOR CH,CH ;GET BASE PORT # MOV CL,CIOBP[BX] XOR AL,AL ;SHUT DOWN 2661 MOV DX,EPCMD ADD DX,CX OUT DX,AL IN AL,DX ;RESET MODE REGISTER POINTER MOV AL,CIOVAL1[BX] ;SET MODE REGISTER 1 MOV DX,EPMODE ADD DX,CX OUT DX,AL MOV AL,CIOVAL2[BX] ;SET MODE REGISTER 2 OR AL,BYTE PTR CIOBR[BX] OUT DX,AL MOV AL,CIOVAL3[BX] ;SET COMMAND REGISTER MOV DX,EPCMD ADD DX,CX OUT DX,AL MOV DX,EPDATA ;FLUSH INPUT BUFFER ADD DX,CX IN AL,DX IN AL,DX POP CX RET ;** PARALLEL PRINTER DRIVER ; ;* INPPRT - INITIALIZE PARALLEL PRINTER PORT ; ; ENTRY: NONE ; EXIT: NONE ; USES: AL,BX ; INPPRT: PUSHF ;INSURE INTERRUPTS ARE DISABLED CLI ; DURING INIT LEA BX,PPRTTBL ;GET ADDRESS OF CIO ENTRY CALL CLRCIO ;CLEAR CIO TABLE FLAGS MOV CIOIN[BX],OFFSET INPPRT ;ADDR OF INIT ROUTINE MOV CIOIS[BX],OFFSET DUMMY ;ADDR OF INPUT INPUT STATUS ROUTINE MOV CIOID[BX],OFFSET IDDUMMY ;ADDR OF INPUT DATA ROUTINE MOV CIOOS[BX],OFFSET OSPPRT ;ADDR OF INPUT OUTPUT STATUS ROUTINE MOV CIOOD[BX],OFFSET ODPPRT ;ADDR OF OUTPUT DATA ROUTINE ; DO PORT A FIRST XOR AL,AL ;ACCESS DATA DIRECTION REG OUT GDPCTLA,AL OUT GDPDDRA,AL ;SET ALL BITS AS INPUTS MOV AL,PIADDAC ;ACCESS PERIPHERAL DATA REG OUT GDPCTLA,AL MOV AL,CIOVAL1[BX] ;SET OUTPUT LATCHES OUT GDPDATA,AL XOR AL,AL ;ACCESS DATA DIRECTION REG OUT GDPCTLA,AL MOV AL,CIOVAL2[BX] ;SET DATA DIRECTION REG OUT GDPDDRA,AL MOV AL,CIOVAL3[BX] ;SET CONTROL PORT VALUE OUT GDPCTLA,AL IN AL,GDPDATA ;CLEAR ANY PENDING INTERRUPTS IN AL,ZDIPSW ;FIRE E-CLOCK MOV AL,CIOVAL1[BX] ;CLEAR LPEN & VSYNC STROBE FLIP-FLOPS AND AL,NOT (LPENSE+VSYNCE) OUT GDPDATA,AL OR AL,LPENSE+VSYNCE OUT GDPDATA,AL ; DO PORT B NEXT XOR AL,AL ;ACCESS DATA DIRECTION REG OUT GDPCTLB,AL OUT GDPDDRB,AL ;SET ALL BITS AS INPUTS MOV AL,PIADDAC ;ACCESS PERIPHERAL DATA REG OUT GDPCTLB,AL MOV AL,CIOVAL4[BX] ;SET OUTPUT LATCHES OUT GDPDATB,AL XOR AL,AL ;ACCESS DATA DIRECTION REG OUT GDPCTLB,AL MOV AL,CIOVAL5[BX] ;SET DATA DIRECTION REG OUT GDPDDRB,AL MOV AL,CIOVAL6[BX] ;SET CONTROL PORT VALUE OUT GDPCTLB,AL IN AL,GDPDATB ;CLEAR ANY PENDING INTERRUPTS IN AL,ZDIPSW ;FIRE E-CLOCK POPF ;RESTORE INTERRUPT STATUS RET ;* OSPPRT - INPUT OUTPUT STATUS BYTE ; ; ENTRY: (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: (AL)=STATUS BYTE ; USES: AL ; OSPPRT: IN AL,GDPDATB ;INPUT STATUS RET ;* ODPPRT - OUTPUT DATA BYTE ; ; ENTRY: (AL)=DATA ; (BX)=ADDRESS OF CIO TABLE ENTRY ; EXIT: NONE ; USES: AH ; ODPPRT: PUSHF ;DISABLE INTERRUPTS WHILE PLAYING CLI ; WITH PORTS MOV AH,AL ;SAVE (AL) OUT GDPDATB,AL ;PLACE PORT B DATA IN OUTPUT LATCH AND AL,PPRTM10 ;MASK FOR PORT A DATA OR AL,CIOVAL1[BX] ;OR IN NON-ASSERTED VALUES FOR OTHER @ ; PORT A OUTPUT BITS OUT GDPDATA,AL ;PLACE PORT A DATA IN OUT PUT LATCH AND AL,0FFH-PPRTSTB ;GENERATE STROBE OUT GDPDATA,AL OR AL,PPRTSTB OUT GDPDATA,AL MOV AL,AH ;RESTORE (AL) POPF ;RESTORE INTERRUPT STATUS RET ;** DUMMY DEVICE DRIVER ; ;* INDUMMY - INITIALIZATION ; ; ENTRY: NONE ; EXIT: NONE ; USES: BX ; INDUMMY: LEA BX,DUMMYTBL ;GET ADDRESS OF CIO TABLE ENTRY CALL CLRCIO ;CLEAR CIO TABLE FLAGS MOV CIOIN[BX],OFFSET INDUMMY ;ADDRESS OF INIT ROUTINE MOV CIOIS[BX],OFFSET DUMMY ;ADDRESS OF INPUT INPUT STATUS BYTE MOV CIOID[BX],OFFSET IDDUMMY ;ADDRESS OF INPUT DATA ROUTINE MOV CIOOS[BX],OFFSET DUMMY ;ADDRESS OF INPUT OUTPUT STATUS BYTE MOV CIOOD[BX],OFFSET DUMMY ;ADDRESS OF OUTPUT DATA ROUTINE RET ;* DUMMY - DUMMY I/O (NOP) ; ; ENTRY: NONE ; EXIT: (AL)=STATUS BYTE ; USES: AL ; DUMMY: RET ;NOP ;* IDDUMMY - INPUT DATA BYTE ; ; ENTRY: NONE ; EXIT: (AL)=DATA BYTE ; USES: AL ; IDDUMMY: MOV AL,CPMEOF ;ALWAYS CP/M ASCII END-OF-FILE RET EJECT ;*** INTERRUPT HANDLERS ; ;** INTDIV0 - DIVIDE BY 0 ; INTDIV0: PUSHA MOV AX,CS MOV DS,AX LEA SI,DIV0MSG ;PRINT MESSAGE AND DUMP CALL PMSG POPA JMP SYSDMP ;** INTPBE - PARITY OR BUSS ERROR HANDLER ; INTPBE: PUSHA MOV AX,CS MOV DS,AX LEA SI,PBEMSG ;PRINT MESSAGE AND DUMP CALL PMSG POPA JMP SYSDMP ;** INTLVK - LIGHTPEN, VSYNC, & KEYBOARD HANDLER ; INTLVK: POP CS: ISAVPC ;SET UP INTERRUPT LOCAL STACK CALL ISETSTK PUSHA IN AL,GDPCTLA ;Q. INTERRUPT FROM PIA TEST AL,LPENSI+VSYNCI JZ INTKEY ; BR IF NOT MOV AH,AL ;SAVE STATUS ;* LIGHTPEN HANDLER TEST AH,LPENSI ;Q. LIGHTPEN STROBE INTERRUPT JZ INTV ; BR IF NOT IN AL,GDPDATA ;CLEAR INTERRUPT AND GET DATA TEST AL,LPEN ;Q. LIGHT PEN HIT INTERRUPT JZ INTV ; BR IF NOT PUSH AX MOV AX,0 ;NEED ADDRESSABILITY TO PAGE 0 MOV ES,AX MOV AL,CRTLPH ;GET LIGHT PEN ADDRESS MSB OUT ZCRTC+CRTREG,AL IN AL,ZCRTC+CRTDAT MOV BH,AL MOV AL,CRTLPL ;GET LIGHT PEN ADDRESS LSB OUT ZCRTC+CRTREG,AL IN AL,ZCRTC+CRTDAT MOV BL,AL ; BX = RELATIVE ADDRESS OF HIT, NOW GET REAL ADDRESS MOV AL,CRTSAH ;GET START ADDRESS MSB OUT ZCRTC+CRTREG,AL IN AL,ZCRTC+CRTDAT MOV AH,AL MOV AL,CRTSAL ;GET START ADDRESS LSB OUT ZCRTC+CRTREG,AL IN AL,ZCRTC+CRTDAT SUB BX,AX ;(BX)=RELATIVE HIT ADDRESS SUB BX,ZLPENEV ; SUBTRACT ERROR VALUE ; MOV ES: LPENHF,1 ;INDICATE LIGHT PEN HIT MOV ES: LPENPOS,BX ;STORE LIGHT PEN POSITION IN AL,ZLPEN ;READ LIGHT PEN HIT REGISTER MOV ES: LPENHIT,AL ; STORE IT POP AX ;* VSYNC HANDLER INTV: TEST AH,VSYNCI ;Q. VSYNC INTERRUPT JZ INTV1 ; BR IF NOT IN AL,GDPDATA ;CLEAR INTERRUPT AND GET DATA TEST AL,VSYNC ;Q. VSYNC STILL PRESENT JZ INTV1 ; BR IF NOT CALLFI MTRTINT,MTRSEG ;CALLF ROM MONITOR ROUTINE ; CLEAR LIGHTPEN STROBE / VERTICAL SYNC INTERRUPTS AND RE-ARM FLIP-FLOPS INTV1: IN AL,GDPDATA ;READ PIA DATA AND AL,NOT (LPENSE+VSYNCE) ;CLEAR LIGHTPEN / VSYNC FLIP-FLOPS OUT GDPDATA,AL IN AL,ZDIPSW ;DUMMY I/O TO FIRE E-CLOCK IN AL,GDPDATA ;ENABLE LIGHTPEN / VSYNC FLIP-FLOPS OR AL,LPENSE+VSYNCE OUT GDPDATA,AL ;* INTKEY - KEYBOARD HANDLER INTKEY: MOV AX,CS ;GET DS MOV DS,AX IN AL,ZKEYBDS ;GET STATUS BYTE TEST AL,ZKEYOBF ;Q. CHARACTER AVAILABLE JZ INTKEY3 ; BR IF NOT IN AL,ZKEYBDD ;INPUT CHARACTER CMP AL,ZKEYBRK ;Q. KEY -- FLUSH TYPE AHEAD BUFS JNE INTKEY0 ; BR IF NOT CALL FLCRT9 ; FLUSH BIOS BUFFER MOV AL,IOBYTE ; IF CRT IS CON:, THEN ALSO AND AL,3 ; FLUSH BDOS 1 CHARACTER BUFFER CMP AL,1 JNE INTKEY3 MOV KBCHAR,0 JMPS INTKEY3 INTKEY0: CMP KEYCNT,KEYBUFF ;Q. KEY BUFFER ALREADY FULL JB INTKEY2 ; BR IF NOT FULL INTKEY1: IN AL,ZKEYBDS ;BUFFER FULL, SEND BEEP TEST AL,ZKEYIBF JNZ INTKEY1 MOV AL,ZKEYBEP OUT ZKEYBDC,AL JMPS INTKEY3 INTKEY2: CALLFI MTRDKBD,MTRSEG ;PASS CHARACTER TO ROM MONITOR HANDLER INTKEY3: POPA JMP INTX2 ;EXIT VIA COMMON IRET EXIT ;** INTWILD - WILD INTERRUPT ;  INTWILD: PUSHA MOV AX,CS MOV DS,AX LEA SI,WILDMSG ;PRINT MESSAGE AND DUMP CALL PMSG POPA JMP SYSDMP ;** SYSDMP - DUMP REGISTERS AT INTERRUPT ; SYSDMP: PUSH DS ;SAVE DS PUSH DI MOV DI,CS ;GET DS MOV DS,DI LEA DI,DMPAX ;AX CALL HEXW POP AX ;DI LEA DI,DMPDI CALL HEXW POP AX ;DS LEA DI,DMPDS CALL HEXW POP AX ;PC LEA DI,DMPIP CALL HEXW POP AX ;CS LEA DI,DMPCS CALL HEXW POP AX ;FLAGS LEA DI,DMPFLG CALL HEXW MOV AX,ES ;ES LEA DI,DMPES CALL HEXW MOV AX,SS ;SS LEA DI,DMPSS CALL HEXW MOV AX,SP ;SP LEA DI,DMPSP CALL HEXW MOV AX,BX ;BX LEA DI,DMPBX CALL HEXW MOV AX,CX ;CX LEA DI,DMPCX CALL HEXW MOV AX,DX ;DX LEA DI,DMPDX CALL HEXW MOV AX,SI ;SI LEA DI,DMPSI CALL HEXW MOV AX,BP ;BP LEA DI,DMPBP CALL HEXW LEA SI,DMPMSG ;PRINT DUMP CALL PMSG ;** HALT SYSTEM ; SYSHLT: LEA SI,HLTMSG ;PRINT MESSAGE CALL PMSG CALLFI MTRTINT,MTRSEG ;CALLF ROM MONITOR TO INSURE SCROLLING SYSHLT1: CLI ;INSURE MACHINE HALTS JMPS SYSHLT1 ;** INTX - INTERRUPT EXIT ROUTINES ; ; INTX1 - ENTERED WHEN HARDWARE SLAVE INTERRUPT ; INTX2 - ENTERED WHEN HARDWARE MASTER INTERRUPT ; INTX3 - ENTERED WHEN SOFTWARE INTERRUPT ; ; EXIT FOR HARDWARE SLAVE INTERRUPT INTX1: PUSH AX MOV AL,OCW2OP+OCW2EOI ;ISSUE NON-SPECIFIC EOI OUT Z8259AS+OCW2,AL MOV AL,OCW3OP+OCW3RIS ;READ ISR OUT Z8259AS+OCW3,AL IN AL,Z8259AS+OCW3 TEST AL,AL ;Q. ANY OTHER SLAVE INT'S IN SERVICE POP AX JNZ INTX3 ; BR IF YES - SKIP EOI TO MASTER ; EXIT FOR HARDWARE MASTER INTERRUPT INTX2: PUSH AX MOV AL,OCW2OP+OCW2EOI ;ISSUE NON-SPECIFIC EOI OUT Z8259AM+OCW2,AL POP AX ; EXIT FOR SOFTWARE INTERRUPTS INTX3: TEST CS: IFLAG,IBIOS ;Q. HANDLER IN BIOS JNZ INTX3A ; BR IF YES POP CS: ISAVPC ;RETRIEVE (PC) JMPS INTX3B INTX3A: MOV SS,CS: ISAVSS ;RESTORE STACK MOV SP,CS: ISAVSP INTX3B: IF R8085 POP CS: ISAVCS PUSH ES CMP CS:R85MEM,0 ;Q. 8085 PROCESS RUNNING JE INTX3C ; BR IF NOT MOV ES,CS:R85MEM TEST ES:COMWHO,ZPSPPS ;Q. 8088 IN CONTROL AT TIME OF INT JNZ INTX3C ; BR IF YES IF ZPSPPS8 NE ZPSPPS %: ZPSPPS8 NE ZPSPPS ENDIF MOV CS:ISAVCS,CS ;ALTER RETURN INFO TO PASS CONTROL MOV CS:ISAVPC,OFFSET SWAP851 ; TO 8085 SWAP ROUTINE INTX3C: POP ES PUSH CS: ISAVCS ENDIF PUSH CS: ISAVPC AND CS: IFLAG,NOT IBIOS IRET ;DO RETURN FROM INTERRUPT ;** SET UP LOCAL STACK FOR INTERRUPT HANDLER ; ; ENTRY: NONE ; EXIT: NONE ; USES: NONE ; ISETSTK: POP CS: ISAVRET ;SAVE RETURN ADDRESS MOV CS: ISAVSS,SS ;SAVE STACK POINTERS MOV CS: ISAVSP,SP MOV CS: ISAVAX,AX ;SET UP LOCAL STACK MOV AX,CS MOV SS,AX LEA SP,ISTACK MOV AX,CS: ISAVAX OR CS: IFLAG,IBIOS ;INDICATE HANDLER IN BIOS & STACK USED JMP CS: ISAVRET ;RETURN USING SAVED RETURN ADDRESS EJECT ;*** SUBROUTINES ; ;** ABTIGN - HANDLE ABORT/IGNORE ALTERNATIVE FOR HARD DISK ERRORS ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER ; 'PHYSEC'=PHYSICAL SECTOR # ; EXIT: 'BUFERR[BX]'=ABORT STATUS (0=NO , 1=YES) ; USES: AX,SI,DI ; ABTIGN: TEST DSKOP,DSKOPS ;Q. ERROR DURING 1ST TIME SELECT JNZ ABTIGN2 ; BR IF YES MOV BUFERR[BX],0 ;ASSUME NO ERROR MOV DI,BUFERRF[BX] ;GET ERROR STATUS BYTE ADD DI,PHYSEC MOV AL,[DI] CMP AL,0 ;Q. ERROR JE ABTIGN2 ; BR IF NO ERROR PUSH BX PUSH DI CALL ERRRPT ;REPORT ERROR LEA SI,AIMSG CALL PMSG CALL GETCHR ;GET RESPONSE PUSH AX LEA SI,CRLF CALL PMSG POP AX POP DI POP BX CMP AL,CTLC ;Q. ABORT RESPONSE JNE ABTIGN1 ; BR IF NO MOV BUFERR[BX],1 ;INDICATE ABORT JMPS ABTIGN2 ABTIGN1: MOV BYTE PTR [DI],0 ;INDICATE IGNORE ERROR ABTIGN2: RET ;** ALTCHR -- HANDLE ALTERNATE CHARACTER FONTS ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; ALTCHR: MOV CL,FAM ;FREE ALL MEMORY TO INIT BDOS INT BDOSE ; MEMORY MANAGEMENT MOV CL,RDS ;RESET BDOS DISK SYSTEM INT BDOSE M OV CL,OPEN ;ATTEMPT TO OPEN FILE LEA DX,ALTCFCB ; 'ALTCHAR.SYS' INT BDOSE INC AL ; JZ ALTCHR9 ; BR IF NOT FOUND JNZ $+5 JMP ALTCHR9 MOV CL,CFSIZE ;COMPUTE FILE SIZE LEA DX,ALTCFCB INT BDOSE MOV AX,WORD PTR ALTCFCB+(OFFSET FCBRR) CMP AX,0 ;Q. NULL FILE ; JE ALTCHR8 ; BR IF YES JNE $+5 JMP ALTCHR8 CMP AX,512 ;Q. FILE SIZE > 64K ; JA ALTCHR8 ; BR IF YES JBE $+5 JMP ALTCHR8 MOV DX,128/16 ;COMPUTE # PARAGRAPHS IN FILE MUL DX MOV MCBLEN,AX ;ALLOCATE SPACE TO READ IN FILE MOV CL,GMREG LEA DX,MCB INT BDOSE INC AL ; JZ ALTCHR8 ; BR IF UNABLE TO ALLOCATE JNZ $+5 JMP ALTCHR8 MOV CL,SDMASB ;SET DMA SEGMENT BASE MOV DX,MCBBASE INT BDOSE XOR DX,DX ;INITIALZE DMA OFFSET ALTCHR0: MOV CL,SETDMA ;SET DMA OFFSET PUSH DX INT BDOSE MOV CL,READ ;READ NEXT CP/M RECORD LEA DX,ALTCFCB INT BDOSE POP DX ;BUMP DMA OFFSET ADD DX,128 CMP AL,0 ;Q. END OF FILE JZ ALTCHR0 ; BR IF NOT XOR AX,AX MOV ES,AX MOV ES,ES:.MTRDSEG ;ES=>MONITOR DATA AREA CMP ES:MTRFNTL,ALTFNTL ;Q. WILL ROM FONT TABLE FIT IN MY AREA JBE ALTCHR1 ; BR IF YES LEA SI,FNTMSG ;PRINT ERROR MESSAGE CALL PMSG JMP SYSHLT ; MOVE ROM FONT TABLE TO MY AREA ALTCHR1: CLD LEA DI,ALTFNT MOV CX,ES:MTRFNTL MOV SI,ES:MTRFONT MOV ES,ES:MTRFONT+2 CALL EXDSES ;DS=>ROM FONT TABLE , ES=>BIOS REP MOVSB CALL EXDSES ;DS=>BIOS , ES=>ROM FONT TABLE ; MAKE CHANGES TO KEYBOARD MAP XOR SI,SI PUSH DS MOV DS,MCBBASE ;DS=>ALTCHAR.SYS FILE DATA XOR AX,AX MOV ES,AX MOV ES,ES:.MTRDSEG ;ES=>MONITOR DATA AREA ALTCHR2: LODSW CMP AX,0FFFFH JE ALTCHR3 MOV DI,AX AND DI,0FFH MOV ES: MTRKMAP[DI],AH JMPS ALTCHR2 ; MAKE CHANGES TO FONT TABLE ALTCHR3: POP ES ;ES=>BIOS ALTCHR4: LODSB CMP AL,0FFH JE ALTCHR5 MOV AH,9 MUL AH LEA DI,ALTFNT ADD DI,AX MOV CX,9 REP MOVSB JMPS ALTCHR4 ; MAKE CHANGES TO DISPLAY MAP ALTCHR5: PUSH ES XOR AX,AX MOV ES,AX MOV ES,ES:.MTRDSEG ;ES=>MONITOR DATA AREA ALTCHR6: LODSW CMP AX,0FFFFH JE ALTCHR7 MOV DI,AX AND DI,0FFH MOV ES: MTRDMAP[DI],AH JMPS ALTCHR6 ; ALTCHR7: POP DS ;DS=>BIOS MOV ES: MTRFONT,OFFSET ALTFNT MOV ES: MTRFONT+2,DS ;UPDATE FONT TABLE VECTOR ALTCHR8: MOV CL,CLOSE ;CLOSE FILE LEA DX,ALTCFCB INT BDOSE MOV CL,FAM ;FREE ALLOCATED MEMORY INT BDOSE ALTCHR9: RET ;** CBTFIL - FILL THE LOGICAL TO PHYSICAL MAPPING TABLE FOR REAL DRIVES. ; = THEN DO THE SAME FOR THE IMAGINARY DRIVES PLUS SET UP THE ; IMAGINARY'S LINK TO HIS CORRESPONDING REAL DRIVE. ; ; ENTRY: (CH)=# DRIVES ; (CL)=STARTING UNIT # ; (DH)=STARTING DRIVE MAP # ; 'CBIC'=NEXT LOGICAL DRIVE # TO BE ASSIGNED ; EXIT: 'CBIC' UPDATED ; USES: ALL ; CBTFIL: MOV CBTIA,0 ;INIT CBTIA CBTFIL1: PUSH CX PUSH DX MOV CBTFA,0 ;INDICATE REAL DRIVE CYCLE CALL CBTF ;HANDLE REAL DRIVES POP DX POP CX MOV CBTFA,1 ;INDICATE IMAGINARY CYCLE ;* THIS SECTION OF CODE IS RAN THROUGH TWICE. ; FIRST TIME IS FOR HANDLING THE REAL DRIVES. ; SECOND TIME IS FOR HANDLING THE IMAGINARY DRIVES. CBTF: MOV DL,CH ;COPY # OF DRIVES CBTF1: MOV AL,CL ;GET THIS DRIVES NUMBER MOD (# DRIVES) CBW DIV CH ADD AH,DH ;COMPUTE DISK ENTRY TABLE TO USE MOV CBIB,AH PUSH CX MOV AL,DPEL ;GET ADDRESS OF TABLE ENTRY MUL AH ADD AX,OFFSET DPEBASE MOV BP,AX TEST DPEFLG2[BP],DPEIMG ;Q. IMAGINARY DRIVE JNZ CBTF3 ; BR IF YES ; HANDLE REAL DRIVE IS THIS IS REAL DRIVE CYCLE CMP CBTFA,0 ;Q. REAL DRIVE CYCLE JNE CBTF4 ; BR IF NOT CMP CBTIA,0 ;IF THIS IS 1ST REAL DRIVE ENCOUNTERED JNE CBTF25 ; THEN REMEMBER ITS TABLE ADDRESS MOV CBTIA,BP CBTF25: MOV CH,CBIC MOV CL,4 SHL CH,CL OR CH,CBIB MOV DPELUN[BP],CH ;PLACE LOGICAL/REAL IN DPELUN SLOT CALL CBTF6 ;MAP DRIVE JMPS CBTF4 ; HANDLE IMAGINARY DRIVE IF THIS IS THE IMAGINARY DRIVE CYCLE CBTF3: CMP CBTFA,0 ;Q. IMAGINARY DRIVE CYCLE JE CBTF4 ; BR IF NOT CMP CBTIA,0 ;Q. ANY REAL DRIVES FOR THIS DRIVE TYPE JNE CBTF31 ; BR IF YES MOV DPEFLAG[BP],DPENE ; OTHERWISE CHANGE DRIVE TYPE TO DEC NDISKS ; NONEXISTANT DRIVE AND DECREMENT JMPS CBTF4 ; # CP/M DRIVES CBTF31: CALL CBTF6 ;MAP DRIVE MOV SI,CBTIA ;MOVE THE REAL DRIVE'S HEATH EXTENSIONS ADD SI,OFFSET DPEHTH ; INTO THIS IMAGINARY DRIVE'S TABLES MOV DI,BP ADD DI,OFFSET DPEHTH PUSH CX MOV CX,DPEHL MOV AX,DS MOV ES,AX CLD REP MOVSB POP CX OR DPEFLG2[BP],DPEIMG ;REMARK AS IMAGINARY DRIVE MOV CH,CBIC ;REENTER LOGICAL DRIVE # MOV CL,4 SHL CH,CL AND DPELUN[BP],DPEREAL OR DPELUN[BP],CH ; CBTF4: POP CX INC CL ;ROUND ROBIN TO NEXT DRIVE DEC DL ;COUNT THIS ONE AS DONE JZ $+5 JMP CBTF1 RET ;* PLACE MAPPED DRIVE # INTO MAP DRIVE TABLE ; 'CBIB'=MAPPED DRIVE # CBTF6: LEA BX,BDMAP ;CALCULATE MAP TABLE ENTRY ADDRESS MOV AL,CBIC CBW ADD BX,AX MOV AL,CBIB MOV [BX],AL ;PLACE MAPPED DRIVE # THERE INC CBIC ;BUMP VALUE NEXT LOGICAL DRIVE # RET ;** CHKLAB - CHECK CHECKSUM OF LABEL ; ; ENTRY: (SI),(ES)=ADDRESS OF LABEL ; EXIT: PSW/Z=STATUS ; 0=BAD CHECKSUM , 1=GOOD CHECKSUM ; USES: AL,CX,SI ; CHKLAB: XOR AL,AL ;ZERO ACCUMULATOR MOV CX,LABLEN ;COUNT CHKLAB1: ADD AL,ES:[SI] ;ADD VALUES INC SI LOOP CHKLAB1 INC AL ;INC CHECKSUM VALUE AND SET/RESET PSW/Z RET ;** CPSEC - CALCULATE PHYSICAL SECTOR ; ; ENTRY: 'REQSEC'=REQUESTED CP/M SECTOR # ; (BX)=ADDRESS OF BUFFER HEADER ; EXIT: (AX),'PHYSEC'=PHYSICAL SECTOR # ; USES: AX,DI ; CPSEC: MOV AX,REQSEC MOV DI,BUFDPE[BX] CMP REQTRK,0 JNE CPSEC1 TEST DPEFLAG[DI],DPET0SD JNZ CPSEC2 CPSEC1: DIV DPERPS[DI] CBW CPSEC2: MOV PHYSEC,AX RET ;** ERRRPT - REPORT DISK ERRORS ; ; ENTRY: (AL)=ERROR STATUS BYTE ; (BX)=ADDRESS OF BUFFER HEADER INFO ; 'PHYTRK'=TRACK # ; 'PHYSEC'=SECTOR # ; 'PHYSID','PHYSIDN'=SIDE INFO ; 'LSIO'=FLAG INDICATING LOGICAL SECTOR I/O RATHER THAN ; TRACK/SIDE/SECTOR ; EXIT: NONE ; USES: CX,SI,DI ; ERRRPT: TEST DSKOP,DSKOPS ;Q. ERROR DURING 1ST TIME SELECT ; JNZ ERRRPT4 ; BR IF YES JZ $+5 JMP ERRRPT4 PUSH AX LEA DI,ERRMSG6 ;STATUS BYTE CALL HEXB MOV AX,DS ;'READ' OR 'WRITE' ERROR MOV ES,AX LEA SI,RDEMSG TEST DSKOP,NOT (DSKOPR+DSKOPRA) JZ ERRRPT1 LEA SI,WREMSG ERRRPT1: LEA DI,ERRMSG1 MOV CX,5 CLD REP MOVSB MOV AL,BUFDRV[BX] ;DRIVE NAME ADD AL,'A' MOV ERRMSG2,AL PUSH BX ;PRINT ERROR MSG SO FAR LEA SI,ERRMSG CALL PMSG POP BX CMP LSIO,1 ;Q. LOGICAL SECTOR I/O DEVICE JE ERRRPT2A ; BR IF YES MOV AX,PHYTRK ;TRACK # LEA DI,ERRMSG3 CALL HEXW XOR AL,AL ;SIDE # MOV DI,BUFDPE[BX] TEST DPEFLAG[DI],DPE2S JZ ERRRPT2 MOV AL,PHYSIDN ERRRPT2: LEA DI,ERRMSG4 CALL HEXN PUSH BX ;AGAIN PRINT ERROR MSG SO FAR LEA SI,ERRMSG7 CALL PMSG POP BX ERRRPT2A: TEST DSKOP,DSKOPR+DSKOPW ;SECTOR # JZ ERRRPT3 MOV AX,PHYSEC INC AX CMP LSIO,1 JNE ERRRPT2B ADD AX,PHYTRK DEC AX ERRRPT2B: LEA DI,ERRMSG5 CALL HEXW PUSH BX ;AGAIN PRINT ERROR MSG SO FAR LEA SI,ERRMSG8 CALL PMSG POP BX ERRRPT3: PUSH BX LEA SI,CRLF CALL PMSG POP BX POP AX ERRRPT4: RET ;** EXDSES -- EXCHANGE DS AND ES ; EXDSES: PUSH DS PUSH ES POP DS POP ES RET ;** GETCHR - GET CHARACTER FROM CON: (FLUSHING TYPEAHEAD BUFFER ; BEFORE HAND IF NECESSARY ; ; ENTRY: NONE ; EXIT: (AL)=CHARACTER ; USES: AL ; GETCHR: MOV AL,IOBYTE ;GET IOBYTE AND AL,003H ;Q. CON:=CRT: CMP AL,1 JNE GETCHR1 ; BR IF NOT CALL FLCRT ;FLUSH CRT: TYPE AHEAD BUFFER GETCHR1: JMP CONINE ;RETURN VIA 'CONINE' ;** GETMEM -- GET NEXT AVAILABLE PARAGRAPH VALUE & UPDATE ; MEMORY TABLE ; ; ENTRY: (NXTAVL)=NEXT AVAILABLE PARAGRAPH ; (AX)=LENGTH OF REQUEST ; EXIT: 'CY' 1=ERROR ; 0=OK , (AX)=PARAGRAPH VALUE ; USES: AX ; GETMEM: PUSH CX ;CALC # PARAGRAPHS REQUESTED PUSH DX MOV DX,0 ADD AX,15 ADC DX,0 MOV CX,16o DIV CX POP DX POP CX ADD AX,NXTAVL ;CALC NEW NEXT CMP AX,TOPMEM ;Q. PAST END OF MEMORY JAE GETMEM1 ; BR IF YES XCHG AX,NXTAVL ;GET RETURN VALUE CLC ;INDICATE NO ERROR RET GETMEM1: STC ;INDICATE ERROR RET ;** HEXW, HEXB, HEXN - CONVERT HEX VALUES TO ASCII ; ; HEXW - WORD ; ENTRY: (AX)=HEX VALUE ; ; HEXB - BYTE ; ENTRY: (AL)=HEX VALUE ; ; HEXN - LOW ORDER NIBBLE ; ENTRY: (AL)=HEX VALUE ; ; ENTRY: (DI)=ADDRESS OF START OF OUTPUT AREA TO RECEIVE ASCII ; EXIT: NONE ; USES: AX,DI ; HEXW: XCHG AL,AH CALL HEXB MOV AL,AH HEXB: PUSH AX SHR AL,1 SHR AL,1 SHR AL,1 SHR AL,1 CALL HEXN POP AX HEXN: AND AL,00FH ADD AL,090H DAA ADC AL,040H DAA MOV [DI],AL INC DI RET ;** PMSG -- PRINT MESSAGE ON CONSOLE ; ; ENTRY: (SI)=ADDRESS OF MESSAGE ENDING WITH 'CPMEOM' CHARACTER ; THE 'CPMEOM' CHARACTER IS NOT PRINTED ; EXIT: NONE ; USES: ALL ; PMSG: LODSB CMP AL,CPMEOM JZ PMSG1 MOV CL,AL PUSH SI CALL CONOUTE POP SI JMPS PMSG PMSG1: RET ;** UPC - TRANSLATE (AL) TO UPPERCASE ; ; ENTRY: (AL)=CHARACTER ; EXIT: (AL)=TRANSLATED CHARACTER ; USES: AL ; UPC: CMP AL,'a' ;CHECK IF LOWER CASE JB UPC1 CMP AL,'z' JA UPC1 ; BR IF NOT AND AL,05FH ;TRANSLATE TO UPPERCASE UPC1: RET EJECT INCLUDE PATHNDLR.LIB EJECT IF R8085 INCLUDE R85PKG.LIB ENDIF EJECT ;*** BIOS TABLES ; X EQU OFFSET $ DSEG ORG X BIOSFLG EQU TRUE INCLUDE BIOSDEF.LIB ; DISK PARAMETER ENTRY TABLES DPE1A RB 0 ;PHYSICAL DRIVE 0 -- Z207 5 1/4" DW 0,0,0,0 DW DIRBUF DW DPB1A DW CSV1A DW ALV1A DB DPEZ207+DPEDD DB 0 DB 0 DB 0 DB DPEUNK DB DPEMO+FDFS6 DB 0 DB 0 IF OFFSET $ - OFFSET DPE1A NE DPEL %: DPE1A IS INCORRECT LENGTH ENDIF DPE1B RB 0 ;PHYSICAL DRIVE 1 -- Z207 5 1/4" DW 0,0,0,0 DW DIRBUF DW DPB1B DW CSV1B DW ALV1B DB DPEZ207+DPEDD DB 1 DB 0 DB 0 DB DPEUNK DB DPEMO+FDFS6 DB 0 DB 0 IF OFFSET $ - OFFSET DPE1B NE DPEL %: DPE1B IS INCORRECT LENGTH ENDIF DPE1C RB 0 ;PHYSICAL DRIVE 2 -- Z207 8" DW XLATE1,0,0,0 DW DIRBUF DW DPB1C DW CSV1C DW ALV1C DB DPEZ207+DPEDD DB CONPC+CONDS8+0 DB 0 DB 0 DB DPEUNK DB FDFS6 DB DPEHLS DB 0 IF OFFSET $ - OFFSET DPE1C NE DPEL %: DPE1C IS INCORRECT LENGTH ENDIF DPE1D RB 0 ;PHYSICAL DRIVE 3 -- Z207 8" DW XLATE2,0,0,0 DW DIRBUF DW DPB1D DW CSV1D DW ALV1D DB DPEZ207+DPEDD DB CONPC+CONDS8+1 DB 0 DB 0 DB DPEUNK DB FDFS6 DB DPEHLS DB 0 IF OFFSET $ - OFFSET DPE1D NE DPEL %: DPE1D IS INCORRECT LENGTH ENDIF DPE2A RB 0 ;Z217 -- PARTITION 1 DW 0,0,0,0 DW DIRBUF DW DPB2A DW 0 DW ALV2A DB DPEZ217+DPEPRIM DB 0 DB WIRPS DB 0 DB 0 DB 0 DB 0 DB 0 IF OFFSET $ - OFFSET DPE2A NE DPEL %: DPE2A IS INCORRECT LENGTH ENDIF DPE2B RB 0 ;Z217 -- PARTITION 2 DW 0,0,0,0 DW DIRBUF DW DPB2B DW 0 DW ALV2B DB DPEZ217 DB 0 DB WIRPS DB 0 DB 0 DB 0 DB 0 DB 0 IF OFFSET $ - OFFSET DPE2B NE DPEL %: DPE2B IS INCORRECT LENGTH ENDIF EJECT ;*** DATA STORAGE ; FNTMSG RB 0 ;ROM FONT TABLE TOO LARGE DB CR,LF,'MONITOR ROM FONT TABLE IS LARGER THAN BIOS ' DB 'FONT TABLE AREA',CPMEOM SIGNON RB 0 ;SIGNON MESSAGE DB CR,LF,LF DB 'CP/M-86 1.1 Release ' IF (BREL/10) NE 0 DB BREL/10+'0' ENDIF DB (BREL MOD 10)+'0' IF EXPER DB 'x' ENDIF IF NOT EXPER DB '.' ENDIF DW BREVSNA DB ' ' DB BMO/10+'0',(BMO MOD 10)+'0','/' DB BDY/10+'0',(BDY MOD 10)+'0','/' DB BYR/10+'0',(BYR MOD 10)+'0' DB CR,LF,LF,CPMEOM MNMSG RB 0 ;MOUNT MESSAGE DB CR,LF,'PUT DISK ' MNMSGA DB '? IN DRIVE ' MNMSGB DB '?: AND PRESS RETURN',CPMEOM ERRMSG RB 0 ;HARD DISK ERROR MESSAGE DB CR,LF,LF,'HARD ' ERRMSG1 DB '? ERROR ON DRIVE ' ERRMSG2 DB '?: STATUS ' ERRMSG6 DB '??',CPMEOM ERRMSG7 DB ' TRACK ' ERRMSG3 DB '???? SIDE ' ERRMSG4 DB '?',CPMEOM ERRMSG8 DB ' SECTOR ' ERRMSG5 DB '????',CPMEOM RDEMSG DB 'READ ' WREMSG DB 'WRITE' AIMSG DB 'PRESS TO ABORT, TO IGNORE: ',CPMEOM CRLF RB 0 DB CR,LF,CPMEOM MTRMSG RB 0 DB BELL,CR,LF,'UNABLE TO MOVE MONITOR ROM DATA AREA',CR,LF,CPMEOM TIMERRM RB 0 ;TIMER BROKE MSG DB BELL,CR,LF,'THE TIMER IS BROKE',CR,LF,CPMEOM BUFMSG RB 0 DB BELL,CR,LF,'NOT ENOUGH MEMORY FOR DISK BUFFERS',CR,LF,CPMEOM DIV0MSG RB 0 ;DIVIDE BY 0 ERROR MESSAGE DB CR,LF,LF,'DIVIDE BY ZERO INTERRUPT',CR,LF,LF,CPMEOM PBEMSG RB 0 ;PARITY OR BUSS ERROR MESSAGE DB CR,LF,LF,'ERROR - MEMORY PARITY OR BUSS',CR,LF,LF,CPMEOM WILDMSG RB 0 ;WILD INTERRUPT MESSAGE DB CR,LF,LF,'WILD INTERRUPT',CR,LF,LF,CPMEOM DMPMSG RB 0 ;REGISTER DUMP DB 'F =' DMPFLG DB '???? IP=' DMPIP DB '???? CS=' DMPCS DB '???? DS=' DMPDS DB '???? ES=' DMPES DB '???? SS=' DMPSS DB '???? SP=' DMPSP DB '????',CR,LF,'AX=' DMPAX DB '???? BX=' DMPBX DB '???? CX=' DMPCX DB '???? DX=' DMPDX DB '???? DI=' DMPDI DB '???? SI=' DMPSI DB '???? BP=' DMPBP DB '????',CPMEOM HLTMSG RB 0 ;SYSTEM HALT MESSAGE DB CR,LF,LF,'SYSTEM HALT',CR,LF,LF,CPMEOM HINTVO RW 0 ;HARDWARE INTERRUPT VECTOR OFFSET TABLE DW OFFSET INTPBE ; MASTER 0 DW OFFSET INTWILD ; MASTER 1 DW OFFSET INTTIM ; MASTER 2 DW OFFSET INTWILD ; MASTER 3 DW OFFSET INTWILD ; MASTER 4 DW OFFSET INTWILD ; MASTER 5 DW OFFSET INTLVK ; MASTER 6 DW OFFSET INTWILD ; MASTER 7 DW OFFSET INTWILD ; SLAVE 0 DW OFFSET INTWILD ; SLAVE 1 DW OFFSET INTWILD ; SLAVE 2 DW OFFSET INTWILD ; SLAVE 3 DW OFFSET INTWILD ; SLAVE 4 DW OFFSET INTWILD ; SLAVE 5 DW OFFSET INTWILD ; SLAVE 6 DW OFFSET INTWILD ; SLAVE 7 DW OFFSET INTX2 ; MASTER EXIT ROUTINE DW OFFSET INTX1 ; SLAVE EXIT ROUTINE DW OFFSET INTX3 ; SOFTWARE INTERRUPT EXIT ROUTINE HINTVON EQU (OFFSET $ - OFFSET HINTVO)/2 DRVRTBL RW 0 ;DEVICE DRIVER DISPATCH TABLE DW 0 ; NON-EXISTANT DW OFFSET DRVR207 ; Z207 DW OFFSET DRVR217 ; Z217 DW 0 DW 0 DW 0 DW 0 DW 0 CBIC DB 0 ;LOGICAL DRIVE # (DRIVE TABLE FILL) DSKOP DB 0 ;DISK OPERATIONS IN PROGRESS DEVCTL DB 0 ;1797 DEVICE CONTROL REGISTER SIDE207 DB FDFSS1 ;1797 SIDE SELECT VALUE LAST USED ; Z207 8" DRIVE TABLES TBL207 RW 0 DW Z2071S ;SINGLE DENSITY / SINGLE SIDED / 128 DW 0 ;SINGLE DENSITY / SINGLE SIDED / 256 DW 0 ;SINGLE DENSITY / SINGLE SIDED / 512 DW 0 ;SINGLE DENSITY / SINGLE SIDED /1024 DW Z2072S ;SINGLE DENSITY / DOUBLE SIDED / 128 DW 0 ;SINGLE DENSITY / DOUBLE SIDED / 256 DW 0 ;SINGLE DENSITY / DOUBLE SIDED / 512 DW 0 ;SINGLE DENSITY / DOUBLE SIDED /1024 DW 0 ;DOUBLE DENSITY / SINGLE SIDED / 128 DW Z2071D1 ;DOUBLE DENSITY / SINGLE SIDED / 256 DW 0 ;DOUBLE DENSITY / SINGLE SIDED / 512 DW Z2071D2 ;DOUBLE DENSITY / SINGLE SIDED /1024 DW 0 ;DOUBLE DENSITY / DOUBLE SIDED / 128 DW Z2072D1 ;DOUBLE DENSITY / DOUBLE SIDED / 256 DW 0 ;DOUBLE DENSITY / DOUBLE SIDED / 512 DW Z2072D2 ;DOUBLE DENSITY / DOUBLE SIDED /1024 Z2071S RB 0 ;SINGLE DENSITY / SINGLE SIDED / 128 DW XLATE1 DB 1,8 DW 26 DB 3,7,0 DW 242,63 DB 0C0H,0 DW 16,2 Z2072S RB 0 ;SINGLE DNESITY / DOUBLE SIDED / 128 DW XLATE1 DB 1,16 DW 26 DB 4,15,1 DW 246,127 DB 0C0H,0 DW 32,2 Z2071D1 RB 0 ;DOUBLE DENSITY / SINGLE SIDED / 256 DW XLATE2 DB 2,16 DW 52 DB 4,15,0 DW 242,127 DB 0C0H,0 DW 32,2 Z2071D2 RB 0 ;DOUBLE DENSITY / SINGLE SIDED /1024 DW 0 DB 8,16 DW 64 DB 4,15,0 DW 299,127 DB 0C0H,0 DW 32,2 Z2072D1 RB 0 ;DOUBLE DENSITY / DOUBLE SIDED / 256 DW XLATE2 DB 2,16 DW 52 DB 4,15,0 DW 493,255 DB 0F0H,0 DW 64,2 Z2072D2 RB 0 ;DOUBLE DENSITY / DOUBLE SIDED /1024 DW 0 DB 8,16 DW 64 DB 4,15,0 DW 607,255 DB 0F0H,0 DW 64,2 XLATE1 RB 0 ;8" SINGLE DENSITY SECTOR TRANSLATE TABLE DB 1,7,13,19,25 DB 5,11,17,23 DB 3,9,15,21 DB 2,8,14,20,26 DB 6,12,18,24 DB 4,10,16,22 XLATE2 RB 0 ;8" DOUBLE DENSITY SECTOR TRANSLATE TABLE DB 1,2,19,20,37,38 DB 3,4,21,22,39,40 DB 5,6,23,24,41,42 DB 7,8,25,26,43,44 DB 9,10,27,28,45,46 DB 11,12,29,30,47,48 DB 13,14,31,32,49,50 DB 15,16,33,34,51,52 DB 17,18,35,36 ; MEMORY REGION TABLE MSEGTBL RB 0 DB 1 NXTAVL DW (B86END+15)/16 MEMAVL DW 0 ; ALTCFCB RB 0 ;FCB FOR FILE 'ALTCHAR.SYS' DB 1,'ALTCHAR SYS',0,0,0,0 DW 0,0,0,0,0,0,0,0 DB 0,0,0,0 IF OFFSET $ - OFFSET ALTCFCB NE FCBLR %: 'ALTCHAR.SYS' FCB IS NOT CORRECT LENGTH ENDIF TODINT RB 0 ;INITIAL SCB DATE & TIME FIELDS DW 0 DB 0,0,0 DB '01/01/78,00:00:00' TODINTL EQU OFFSET $ - OFFSET TODINT TODDAYS RW 0 ;NUMBER OF DAYS IN EACH MONTH DW '31' ; JAN DW '28' ; FEB DW '31' ; MAR DW '30' ; APR DW '31' ; MAY DW '30' ; JUN DW '31' ; JUL DW '31' ; AUG DW '30' ; SEP DW '31' ; OCT DW '30' ; NOV DW '31' ; DEC IOBYTE DB 0 1B ;I/O MAPPING BYTE ; (VALUE AT COLD BOOT IS CON:=CRT:) ; PATCH RB 128 ;PATCH AREA ; CBTFA RB 1 ;DRIVE TABLE FILL CYCLE INDICATOR CBTIA RW 1 ;ADDRESS OF REAL DRIVE DPE CBIB RB 1 ;MAPPED DRIVE # DMAPTR RW 1 ;DMA ADDRESS (OFFSET) DMASEG RW 1 ;DMA ADDRESS (SEGMENT) IF (OFFSET DMASEG) NE (OFFSET DMAPTR + 2) %: DMASEG DOES NOT IMMEDIATELY FOLLOW DMAPTR ENDIF BWRFLG RB 1 ;WRITE TYPE FLAG FVFLG RB 1 ;FORMAT VERIFY FLAG HSTPTR RW 2 ;HOST BUFFER POINTER (OFFSET,SEGMENT) LSIO RB 1 ;LOGICAL SECTOR I/O FLAG PHYDRV RB 1 ;PHYSICAL DRIVE # PHYDPE RW 1 ;PHYSICAL DPE PHYSID RB 1 ;PHYSICAL SIDE PHYSIDN RB 1 ;PHYSICAL SIDE NUMBER PHYTRK RW 1 ;PHYSICAL TRACK PHYSEC RW 1 ;PHYSICAL SECTOR REQDRV RB 1 ;REQUESTED DRIVE REQTRK RW 1 ;REQUESTED TRACK REQSEC RW 1 ;REQUESTED SECTOR SECCNT RB 1 ;PHYSICAL SECTORS PER TRACK SEC1ST RB 1 ;1ST SECTOR # FOR OPERATION COUNT RW 1 ;BYTES PER PHYSICAL SECTOR RETRIES RB 1 ;I/O RETRY COUNTER HLDDLYF RB 1 ;1797 DELAY FLAG ERRTYP RB 1 ;ERROR TYPE (STATUS BYTE) RDABUF RB FDRAL ;READ ADDRESS BUFFER RDABUF2 RB FDRAL ;READ ADDRESS BUFFER OMDSEG RW 1 ;ORIGINAL MONITOR DATA SEGMENT VALUE PREREAD RB 1 ;DO PREREAD FLAG FLDERR RB 1 ;FLUSH DRIVE ERROR ACCUMULATOR PTICCNT RW 1 ;PREVIOUS TIMER 1 COUNT TICCNT RW 2 ;TIC COUNTER (32 BIT) TIMEFLG RB 1 ;TIMER 2 FLAG (1=TIMER FIRED) TODHSEC RW 1 ;TOD TIME HUNDREDTHS OF SECOND CPMSCB RW 1 ;CP/M-86 SYSTEM CONTROL BLOCK OFFSET TOPMEM RW 1 ;TOP OF MEMORY BDMAP RB 16 ;LOGICAL TO PHYSICAL DRIVE MAP DIRBUF RB 128 ;DIRECTORY SECTOR BUFFER DPB1A RB DPBL CSV1A RB 64 ALV1A RB 77 DPB1B RB DPBL CSV1B RB 64 ALV1B RB 77 DPB1C RB DPBL CSV1C RB 64 ALV1C RB 77 DPB1D RB DPBL CSV1D RB 64 ALV1D RB 77 DPB2A RB DPBL ALV2A RB 256 DPB2B RB DPBL ALV2B RB 256 ; MCB RB 0 ;MEMORY CONTROL BLOCK MCBBASE RW 1 MCBLEN RW 1 MCBEXT RB 1 ; KEYBOARD TYPE-AHEAD BUFFER KEYCNT RB 1 ;CHARACTER COUNT KEYPUT RW 1 ;PUT POINTER KEYGET RW 1 ;GET POINTER KEYBUF RB 80 ;BUFFER KEYBUFL EQU OFFSET $ - OFFSET KEYBUF ;BUFFER SIZE KEYBUFF EQU KEYBUFL-10 ;KEYBOARD BUFFER FULL VALUE ; ALTERNATE CHARACTER FONT TABLE ALTFNTL EQU (256-32)*9 ;LENGTH ALTFNT RB ALTFNTL ;AREA ; STACK FOR COLD BOOT RW 64 STACK RW 0 ; STACK FOR MONITOR CALLS RW 512 MSTACK RW 0 MSAVSS RW 1 MSAVSP RW 1 ; STACK FOR INTERRUPT HANDLERS RW 128 ISTACK RW 0 ISAVRET RW 1 ISAVAX RW 1 ISAVCS RW 1 ISAVPC RW 1 ISAVSS RW 1 ISAVSP RW 1 IFLAG RB 1 IBIOS EQU 0W1B ;INT HANDLER IN BIOS & INTERNAL STACK USED ; DISK BUFFER AND BUFFER HANDLING STORAGE BUFCNT RW 1 ;NUMBER OF BUFFERS FSTBUF RW 1 ;POINTER TO FIRST ELEMENT LSTBUF RW 1 ;POINTER TO LAST ELEMENT DMYHDR RB BUFHDRL ;DUMMY BUFFER HEADER HEADER RB BUFMCNT*BUFHDRL ;DISK BUFFER HEADER INFO STACK SECFLGL EQU BUFMNS DSECFLG RB SECFLGL ;DUMMY BUFFER SECTOR FLAGS SECFLG RB BUFMCNT*SECFLGL ;DIRTY SECTOR FLAGS (1=DIRTY) ERRFLGL EQU BUFMNS DERRFLG RB ERRFLGL ;DUMMY BUFFER SECTOR ERROR FLAGS ERRFLG RB BUFMCNT*ERRFLGL ;SECTOR ERROR FLAGS B86END EQU OFFSET $ END " TITLE 'CP/M-86 BOOT CODE FOR Z207 _ 21 APR 83' ;*** ; ; CP/M-86 BOOT CODE FOR Z207 ; ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; FALSE EQU 0 TRUE EQU NOT FALSE WAIT EQU TRUE ;DISK I/O WITH WAIT STATES DSEG INCLUDE ZMEMMAP.LIB INCLUDE ZMTR100.LIB INCLUDE Z207DEF.LIB INCLUDE ZDPEDEF.LIB INCLUDE ZPORTS.LIB CSEG ORG BOOTORG ; ; UPON ENTRY FROM THE MONITOR ROM IT IS ASSUMED ; 1) THE Z207 MOTOR IS ON ; 2) THE HEAD IS OVER TRACK 0 ; CLDR: JMP CLDR0 ;JUMP AROUND FLAGS L_1 EQU $ DSEG ORG Offset L_1-1 PSPT RB 1 DB DPEZ207 ;DRIVE TYPE ; ; VALUES SET BY 'SYSGEN'. ; RB 1 ;LABEL FORM # HEATH RS DPEHL ;HEATH EXTENSIONS DPB RS DPBL ;DISK PARAMETER BLOCK RB 1 ;CHECKSUM COUNT EQU HEATH+OFFSET DPETRK-OFFSET DPEHTH L_2 EQU $ CSEG ORG OFFSET L_2 ; ; SET SEGMENT REGS. ; CLDR0: CLI MOV AX,CS MOV DS,AX MOV ES,AX MOV SS,AX ;SET STACK AREA MOV SP,BOOTORG+BCODEL+256 ; ; SET VALUES FOR LOAD BASED ON FLAGS SET BY SYSGEN. ; MOV AL,DPB+OFFSET DPBSPT ;CALCULATE PHYSICAL # OF SECTORS MOV BL,HEATH+OFFSET DPERPS-OFFSET DPEHTH ; PER TRACK CBW DIV BL MOV PSPT,AL MOV DH,AL MOV AL,128 ;CALCULATE # BYTES PER SECTOR MUL BL MOV WORD PTR COUNT,AX MOV CX,AX MOV AL,HEATH+OFFSET DPEUNIT-OFFSET DPEHTH ;GET 8" FLAG AND AL,CONDS8 OR AL,CONSD+CONDSEN ;SINGLE DENSITY & DISK SELECT ENABLE PUSH DS ;GET UNIT # MOV DS,.MTRDSEG OR AL,MTRBU POP DS MOV AH,HEATH ;GET FLAGS TEST AH,DPET0SD JNZ CLDR1 MOV SPSPT,DH MOV SCOUNT,CX MOV RPS,BL TEST AH,DPEDD ;CHECK BIT DENSITY JZ CLDR1 ; BR IF SINGLE DENSITY AND AL,NOT CONSD ;SET FOR DOUBLE DENSITY CLDR1: TEST AH,DPE2S ;CHECK NUMBER OF SIDES JNZ CLDR2 ; BR IF DOUBLE SIDED MOV SIDES,0 ;SAVE NUMBER OF SIDES FLAG ; ; LOAD SYSTEM FROM SYSTEM TRACKS ; CLDR2: MOV HEATH+OFFSET DPEUNIT-OFFSET DPEHTH,AL ;SAVE BASE CONTROL WORD IF WAIT OR AL,CONWE ;ENABLE WAIT STATE I/O ENDIF OUT FDCON,AL ;SELECT DRIVE MOV DL,NSBT37-1 ;NUMBER OF CP/M RECORDS TO BE LOADED CLD ;SET BUFFER DIRECTION MOV BX,1 ;INIT SIDE & SECTOR # CLDR3: CMP BL,0 ;Q. COMPLETE TRACK READ L_2A EQU $ DSEG ORG OFFSET L_2A-1 SPSPT DB 26 CSEG $ JBE CLDR5 ; BR IF NOT MOV BL,1 ;RESET SECTOR # XOR BH,0 ;UPDATE SIDE FLAG L_3 EQU $ DSEG ORG OFFSET L_3-1 SIDES DB FDFSS1 CSEG $ JNZ CLDR5 ;BR IF NOT TIME TO STEP HEAD CALL STEPIO ;STEP HEAD IN 1 TRACK TEST BYTE PTR HEATH,DPE48RO ;CHECK IF 48 TPI MEDIA ON 96 TPI DRIVE JZ CLDR5 ; BR IF NOT CLDR4C: CALL STEPIO ;STEP HEAD AGAIN CLDR5: MOV AL,BL ;GET SECTOR # OUT FDSEC,AL ;TELL CONTROLLER WHICH SECTOR MOV CX,0 ;GET SECTOR BYTE COUNT L_3A EQU $ DSEG ORG OFFSET L_3A-2 SCOUNT DW 128 CSEG $ MOV DI,0 ;GET BUFFER POINTER L_4 EQU $ DSEG ORG OFFSET L_4-2 DMAPTR DW LDCPMOS-BCODEL CSEG $ MOV AL,FDCRDS+FDFSLF+FDFDLF ;READ COMMAND OR AL,BH ;OR IN SIDE FLAG OUT FDCMD,AL ;ISSUE READ COMMAND CLDR6: IF NOT WAIT IN AL,FDAS ;WAIT FOR DRQ OR IRQ TEST AL,ASDRQ+ASIRQ JZ CLDR6 ENDIF IN AL,FDDAT ;GET DATA STOSB ;STORE IN BUFFER LOOP CLDR6 ;LOOP AND READ CALL WAITIO1 ;WAIT FOR IRQ AND GET STATUS TEST AL,AL ;CHECK FOR ERROR JNZ RDERR ; BR IF ERROR MOV DMAPTR,DI ;SAVE UPDATED BUFFER POINTER INC BL ;BUMP SECTOR # M;UPDATE CP/M RECORD COUNTER SUB DL,0 ; BY SUBTRACTIN CP/M RECORDS PER SECTOR L_5 EQU $ DSEG ORG OFFSET L_5-1 RPS DB 1 CSEG $ JNS CLDR3 ; ; DONE LOADING SYSTEM. ; PASS TO CP/M-86 LOADER. ; DONE: MOV AL,HEATH+OFFSET DPEUNIT-OFFSET DPEHTH ;DISABLE WAIT STATE I/O OUT FDCON,AL JMPF CCP ;JMP TO CP/M-86 rLOADER ; ; HANDLE READ ERRORS. ; RDERR: TEST AL,FDSRNF ;CHECK IF RNF JZ BOOTERR ; BR IF NOT -- FATAL ERROR MOV AL,HEATH+OFFSET DPEUNIT-OFFSET DPEHTH TEST AL,CONDS8 JZ RDERR1 ;BR IF NOT 8" DRIVE TEST AL,CONSD JZ BOOTERR ;BR IF ALREADY DOUBLE DENSITY AND AL,NOT CONSD MOV HEATH+OFFSET DPEUNIT-OFFSET DPEHTH,AL IF WAIT OR AL,CONWE ENDIF OUT FDCON,AL MOV AL,PSPT MOV SPSPT,AL MOV AX,WORD PTR COUNT MOV SCOUNT,AX MOV AL,HEATH+OFFSET DPERPS-OFFSET DPEHTH MOV RPS,AL JMPS CLDR5 ;RETRY OPERATION AT DOUBLE DENSITY RDERR1: MOV AL,HEATH ;ASSUME 'RNF' DUE TO 48 TPI MEDIA P ; IN 96 TPI DRIVE OR BYTE PTR HEATH,DPE48RO ;FLAG TO DOUBLE STEP FROM NOW ON ~;FATAL ERROR IF FLAG BYTE INDICATES TEST AL,DPE48RO+DPE96T ; MEDIA SYSGENED ON 96 TPI DRIVE JZ CLDR4C ; OR ALREADY DOUBLE STEPPING ; ; BOOT ERROR. ; BOOTERR: XOR AL,AL ;TURN OFF Z207 OUT FDCON,AL JMPF MONITOR ;JMPF TO MONITOR ; ; STEP HEAD IN 1 TRACK. ; STEPIO: MOV AL,FDCSTI+FDFUTR+FDFHLB+FDFS30 ;I/O COMMAND ; ; ISSUE Z207 COMMAND AND WAIT FOR COMPLETION. ; WAITIO: OUT FDCMD,AL ;ISSUE COMMAND WAITIO1: IN AL,FDAS ;WAIT FOR IRQ TEST AL,ASIRQ JZ WAITIO1 WAITIO2: IN AL,FDSTA ;GET FINAL STATUS TEST AL,FDSNRD ;Q. READY JNZ WAITIO2 ; BR IF NOT (SOME DRIVES STACK STEP & ; PULSES; THEREFORE, CONTROLLER CAN ; CAN INDICATE DONE WHEN DRIVE IS NOT) RET ; IF (OFFSET $-OFFSET CLDR) GT BCODEL %: BOOT LOADER IS TOO LARGE ENDIF CSEG LDCPMOS/16 ORG LDCCP CCP: CSEG MTRSEG ORG MTRRES MONITOR: END  TITLE 'FORMAT - CP/M-86 FORMAT UTILITY 08 JUN 83' ;*** ; ; THIS IS THE ZDS CP/M-86 FORMAT UTILITY ; ; COPYRIGHT (C) 1983, ZENITH DATA SYSTEMS CORP. ; ; MODULE GENERATION ; GENCMD FORMAT ; ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; FALSE EQU 0 TRUE EQU NOT FALSE REVSN EQU 0 DSEG INCLUDE CPM86SYS.LIB INCLUDE CIOTABLE.LIB BIOSFLG EQU FALSE INCLUDE BIOSDEF.LIB INCLUDE SBCDEF.LIB INCLUDE Z207DEF.LIB INCLUDE Z217DEF.LIB INCLUDE ZDPEDEF.LIB INCLUDE LABDEF.LIB INCLUDE ASCII.LIB EJECT DSEG ORG 0100H CSEG ORG 0000H MOV AX,DS ;SET UP STACK MOV SS,AX LEA SP,STACK MOV CL,PRCONB ;PRINT SIGNON MESSAGE LEA DX,SIGNON INT BDOSE CALL FGBT ;GET ADDRESS OF BIOS TABLES MOV OSDS,ES CMP ES:BIOSREL[BX],BREL ;Q. CORRECT RELEASE OF BIOS JE FMT0 ; BR IF YES MOV CL,PRCONB LEA DX,BADBIOS INT BDOSE JMP FMT6 FMT0: MOV CL,GMREG ;REQ MEMORY FOR BUFFER LEA DX,MCB INT BDOSE CMP AL,0 JE FMT0A ; BR IF REQ HONORED MOV CL,PRCONB LEA DX,NOMEM INT BDOSE JMP FMT6 FMT0A: CMP TBUFF,0 ;Q. COMMAND LINE PRESENT JE FMT1 ; BR IF NOT CALL CLINT ;INTERPRET COMMAND LINE ; JC FMT6 ; BR IF ERROR JNC $+5 JMP FMT6 FMT1: CMP NOQFLG,0 ;Q. ASK IF THIS IS WHAT USER WANTS JNE FMT2 ; BR IF DON'T ASK MOV CL,PRCONB ;ASK USER LEA DX,SIGNON1 INT BDOSE MOV CL,RDCON INT BDOSE CALL TOUPPER CMP AL,'Y' ;Q. YES REPLY ; JNE FMT6 ; BR IF NOT JE $+5 JMP FMT6 ; GET DRIVE TO FORMAT FMT2: MOV AL,DRIVID ;GET DRIVE (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE FMT2A ; BR IF YES MOV CL,PRCONB ;ASK FOR DRIVE  LEA DX,WHICH INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CTLC ;Q. CTL-C JE FMT5 ; BR IF YES -- ABORT FMT2A: CALL TOUPPER MOV DRIVID,AL MOV DRMSGA,AL MOV PROMPTA,AL CALL WKIND ;DETERMINE DRIVE TYPE JNC FMT2B ; BR IF NO ERROR MOV CL,PRCONB LEA DX,DRMSG INT BDOSE JMPS FMT4 FMT2B: CMP DRIVID,'A' ;Q. SYSTEM DRIVE INVOLVED JNE FMT3 ; BR IF NOT MOV SYSDSK,1 ; OTHERWISE REMEMBER ; FMT3: CALL DISPATCH ;FORMAT DISK JC FMT9 ; BR IF ERROR FMT4: CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE FMT5 ; BR IF YES MOV CL,PRCONB ;ASK IF ANY MORE FORMATTING TO BE DONE LEA DX,AMWMSG INT BDOSE MOV CL,RDCON INT BDOSE CALL TOUPPER CMP AL,'Y' JE FMT2 ;BR IF YES FMT5: CMP SYSDSK,0 ;Q. SYSTEM DISK INVOLVED JE FMT6 ; BR IF NOT MOV CL,PRCONB ;WAIT FOR SYSTEM TO DISK TO BE LEA DX,LVEMSG ; REINSERTED INT BDOSE MOV CL,RDCON INT BDOSE FMT6: MOV CL,RDS ;RESET DISK SUBSYSTEM INT BDOSE MOV CL,RESET ;WARM BOOT XOR DL,DL INT BDOSE ; ERROR DURING FORMATTING FMT9: CALL FWPC ;Q. DISK WRITE PROTECTED LEA DX,WPEMSG CMP AL,0 JNE FMT9A ; BR IF YES LEA DX,BMSG FMT9A: MOV CL,PRCONB ;PRINT ERROR MESSAGE INT BDOSE JMPS FMT4 EJECT ;** FORMAT Z207. ; F207: MOV AL,'D' ;5 1/4" DRIVE USE DOUBLE DENSITY TEST AIOUNI,CONDS8 JZ F2072 ;BR IF 5 1/4" DRIVE F2071: MOV AL,CLIDENS ;GET DENSITY (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE F2072 ; BR IF YES MOV CL,PRCONB ;ASK FOR DENSITY LEA DX,WDSDMSG INT BDOSE MOV CL,RDCON INT BDOSE F2072: CALL TOUPPER MOV AH,0 ;ASSUME SINGLE DENSITY CMP AL,'S' ;Q. SINGLE DENSITY JE F2073 ; BR IF YES MOV AH,DPEDD ;DOUBLE DENSITY CMP AL,'D' ;Q. DOUBLE DENSITY JE F2073 ; BR IF YES MOV CL,PRCONB LEA DX,ERRMSG INT BDOSE CMP COMLIN,0 JE F2071 JMP F20749 F2073: MOV DENSITY,AH ;SAVE DENSITY MOV AL,'2' ;ASSUME DOUBLE SIDED TEST AIOUNI,CONDS8 ;Q. 8" DRIVE JNZ F2075 ; BR IF YES F2074: MOV AL,CLISIDS ;GET SIDES (ASSUME COMMAND LINE) CMP COMLIN,0 ;Q. COMMAND LINE PRESENT JNE F2075 ; BR IF YES MOV CL,PRCONB ;ASK FOR # SIDES LEA DX,WSMSG INT BDOSE MOV CL,RDCON INT BDOSE F2075: MOV AH,0 ;ASSUME SINGLE SIDED CMP AL,'1' ;Q. SINGLE SIDED JE F2076 ; BR IF YES MOV AH,DPE2S ;ASSUME DOUBLE SIDED CMP AL,'2' ;Q. DOUBLE SIDED JE F2076 ; BR IF YES MOV CL,PRCONB LEA DX,ERRMSG INT BDOSE CMP COMLIN,0 JE F2074 JMP F20749 F2076: MOV SIDES,AH ;SAVE # SIDES CMP NOQFLG,0 ;Q. NO QUERY SWITCH SET JNE F2077 ; BR IF YES MOV CL,PRCONB ;ASK TO INSERT DISK LEA DX,PROMPT INT BDOSE MOV CL,PRCONB ;ASK IF READY LEA DX,PROMPT1 INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CR ;Q. ; JNE F20748 ; BR IF NOT JE $+5 JMP F20748 F2077: CALL F20770 ;FILL IN DPE & DPB MOV TRACK,0 ;CLEAR WORK VALUES MOV AX,NTRK837 ;DETERMINE # CP/M TRACKS TEST AIOUNI,CONDS8 JNZ F2078 MOV AX,NTRKS37 TEST DRTYPE,DPE96T JZ F2078 MOV AX,NTRKD37 F2078: CMP SIDES,DPE2S JNE F2079 SHL AX,1 F2079: MOV DSKTKS,AX LES BX,DWORD PTR DPEPTR ;FORCE RESTORE BY SETTING TRACK POINTER MOV ES:DPETRK[BX],DPEUNK ; TO UNKOWN ; IF 8" DRIVE AND TRACK 0 / SIDE 0 IS SINGLE DENSITY ; THEN FORMAT TRACK 0 / SIDE 0 TEST AIOUNI,CONDS8 ;Q. 8" DRIVE JZ F20740 ; BR IF NOT TEST DRTYPE,DPET0SD ;Q. CP/M TRACK 0 SINGLE DENSITY JZ F20740 ; BR IF NOT LEA SI,F207STBL ;BUILD TRACK IMAGE CALL F20780 CALL F20750 ;FORMAT TRACK CMP AL,0 ;Q. ERROR JNE F20749 ; BR IF ERROR ; FORMAT SURFACE(S) F20740: LEA SI,F207D2TB ;DETERMINE WHICH TABLE TO USE TEST AIOUNI,CONDS8 ; TO BUILD TRACK IMAGE JZ F20741 LEA SI,F207STBL CMP DENSITY,DPEDD JNE F20741 LEA SI,F207DTBL F20741: CALL F20780 ;BUILD TRACK IMAGE F20742: CALL F20750 ;FORMAT TRACK CMP AL,0 ;Q. ERROR JE F20743 ; BR IF NOT CMP AL,FDSNRD ;IF NOT READY ERROR ON 8" DRIVE AND JNE F20749 ; TRYING TO FORMAT DOUBLE SIDED, THEN TEST AIOUNI,CONDS8 ; SWITCH TO SINGLE SIDED AND JZ F20749 ; TRY AGAIN CMP TRACK,1 JNE F20749 CMP SIDES,DPE2S JNE F20749 MOV SIDES,0 JMP F2077 ; F20743: MOV AX,TRACK ;Q. ALL TRACKS DONE CMP AX,DSKTKS JNE F20742 ; BR IF NOT ; FORM LABEL AND WRITE IT TO TRACK 0 / SECTOR 1 / SIDE 0 CALL WRLAB JC F20749 ;BR IF ERROR ; ALL DONE F20748: CLC ;INDICATE NO ERROR RET ; ERROR F20749: STC ;INDICATE ERROR RET ;* FORMAT TRACK F20750: CALL F20790 ;SET TRACK/SIDE/SECTOR VALUES IN TRACK IMAGE MOV CX,TRACK ;SET DESIRED CP/M TRACK # CALL FSETTRK MOV CX,0 ;SET DMA OFFSET CALL FSETDMA MOV CX,BUFFER ;SET DMA SEGMENT CALL FSETDMAS MOV CL,1 ;ASSUME VERIFY CMP FAST,0 ;Q. FAST JE F20751 ; BR IF NOT MOV CL,0 ; NO VERIFY F20751: CALL FFORMAT ;FORMAT TRACK CMP AL,0 ;Q. ERROR JNE F20752 ; BR YES INC TRACK ;BUMP TRACK COUNTER F20752: RET ;* FILL DPE & DPB F20770: MOV AL,0 ;DETERMINE WHICH TABLE TO USE TEST AIOUNI,CONDS8 JNZ F20771 TEST DRTYPE,DPE96T JZ F20772 MOV AL,2 JMPS F20772 F20771: MOV AL,4 CMP DENSITY,DPEDD JNE F20772 MOV AL,6 F20772: CMP SIDES,DPE2S JNE F20773 INC AL F20773: MOV AH,F207TBLL MUL AH ADD AX,OFFSET F207TBL MOV SI,AX ;(SI)=TABLE ADDRESS LES BX,DWORD PTR DPEPTR ;GET ADDRESS OF DPE CLD LODSB ;DPE FLAG BYTE 1 AND ES:DPEFLAG[BX],NOT (DPE48RO+DPEDD+DPE2S) OR ES:DPEFLAG[BX],AL TEST AIOUNI,CONDS8 ; Q. 8" DRIVE JZ F20774 ; BR IF NOT AND ES:DPEFLAG[BX],NOT DPET0SD AND DRTYPE,NOT DPET0SD CMP DENSITY,DPEDD ; Q. DOUBLE DENSITY REQUESTED JNE F20774 ; BR IF NOT CMP CLID0,0 ; Q. FORMAT TRACK 0 DOUBLE DENSITY JNE F20774 ; BR IF YES OR ES:DPEFLAG[BX],DPET0SD ; SET FLAG FOR TRACK 0 SINGLE DENSITY OR DRTYPE,DPET0SD F20774: LODSB ;CP/M RECORDS PER SECTOR MOV ES:DPERPS[BX],AL LODSB ;CP/M RECORDS PER ALLOCATION BLOCK MOV ES:DPERPAB[BX],AL LODSB ;MEDIA TPI AND ES:DPEFLG2[BX],NOT DPE96TM OR ES:DPEFLG2[BX],AL LES DI,DWORD PTR DPBPTR ;FILL IN DPB MOV CX,DPBL CLD REP MOVSB RET ;* BUILD TRACK IMAGE F20780: CLD LODSB ;SPT MOV DSKSPT,AL MOV DI,0 ;START OF TRACK IMAGE MOV ES,BUFFER F20781: LODSB ;FILL IN FRONT END GAP CMP AL,0 ;Q. END OF FRONT END GAP INFO JE F20782 ; BR IF YES XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20781 F20782: MOV F207B,DI MOV F207C,0 MOV F207D,0 MOV DL,DSKSPT ;GET SECTORS PER TRACK MOV BX,SI ;REMEMBER START OF SECTOR DESCRIPTORS F20783: MOV SI,BX ;FILL IN FOR A SECTOR F20784: LODSB CMP AL,0 JNE F20784A ; BR IF NOT TRACK # MARKER CMP F207C,0 ; Q. TRACK OFFSET DETERMINED JNE F20784B ; BR IF YES MOV F207C,DI ; OTHERWISE SAVE TRACK OFFSET JMPS F20784B F20784A: XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20784 F20784B: LODSB CMP AL,0 JNE F20784C ; BR IF NOT END OF SECTOR MARKER CMP F207D,0 ; Q. LENGTH OF SECTOR DETERMINED JNE F20785 ; BR IF YES MOV AX,DI ; OTHERWISE CALC LENGTH SUB AX,F207B MOV F207D,AX JMPS F20785 F20784C: XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20784B F20785: DEC DL ;Q. ALL SECTORS DONE JNZ F20783 ; BR IF NOT F20786: LODSB ;FILL REQUIRED GAP IV AMOUNT XOR CH,CH MOV CL,AL LODSB REP STOSB F20787: LODSB ;FILL OPTIONAL GAP IV AMOUNT CMP AL,0 JE F20788 XOR CH,CH MOV CL,AL LODSB REP STOSB JMPS F20787 F20788: RET ;* FILL IN TRACK/SIDE/SECTOR VALUES FOR THIS ITERATION IN TRACK IMAGE F20790: MOV DX,TRACK ;CALCULATE PHYSICAL TRACK/SIDE VALUES XOR DH,DH CMP SIDES,DPE2S JNE F20791 SHR DL,1 JNC F20791 MOV DH,1 F20791: MOV DI,F207C MOV ES,BUFFER CLD XOR CH,CH MOV CL,DSKSPT MOV BL,1 F20792: MOV SI,DI MOV AX,DX STOSW MOV AL,BL STOSB INC BL MOV DI,SI ADD DI,F207D LOOP F20792 F20793: RET ;* DSEG $ F207B RW 1 ;ADDR OF 1ST SECTOR IN BUF FER F207C RW 1 ;OFFSET INTO 1ST SECTOR OF TRACK # F207D RW 1 ;SIZE OF SECTOR F207STBL RB 0 ;8" SINGLE DENSITY TRACK FORMAT TABLE DB 26 ; SECTORS PER TRACK DB 40,0FFH ; TRACK HEADER GAP DB 6,0 DB 1,0FCH DB 26,0FFH DB 0 DB 6,0 ; SECTOR AREA (REPEAT FOR SPT) DB 1,0FEH DB 0 ; TRACK # OFFSET MARKER DB 4,0 DB 1,0F7H DB 11,0FFH DB 6,0 DB 1,0FBH DB 128,0E5H DB 1,0F7H DB 27,0FFH DB 0 DB 24,0FFH ; REQUIRED GAP IV AMOUNT DB 255,0FFH ; OPTIONAL GAP IV AMOUNT DB 124,0FFH DB 0 F207DTBL RB 0 ;8" DOUBLE DENSITY 26X256 TRACK FORMAT DB 26 DB 80,04EH DB 12,0 DB 3,0F6H DB 1,0FCH DB 50,04EH DB 0 DB 12,0 DB 3,0F5H DB 1,0FEH DB 0 DB 3,0 DB 1,1 DB 1,0F7H DB 22,04EH DB 12,0 DB 3,0F5H DB 1,0FBH DB 128,0E5H DB 128,0E5H DB 1,0F7H DB 54,04EH DB 0 DB 24,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 121,04EH DB 0 F207D2TB RB 0 ;5 1/4" FORMAT TABLE DB 8 DB 80,04EH DB 12,0 DB 3,0F6H DB 1,0FCH DB 50,04EH DB 0 DB 12,0 DB 3,0F5H DB 1,0FEH DB 0 DB 3,0 DB 1,2 DB 1,0F7H DB 22,04EH DB 12,0 DB 3,0F5H DB 1,0FBH DB 128,0E5H DB 128,0E5H DB 128,0E5H DB 128,0E5H DB 1,0F7H DB 80,04EH DB 0 DB 24,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 255,04EH DB 15,04EH DB 0 ; Z207 DISK DESCRIPTORS FOR LABEL ; ; DB DENSITY/SIDES FLAGS ; DB CP/M RECORDS PER SECTOR ; DB CP/M RECORDS PER ALLOCATION BLOCK ; DB MEDIA TPI FLAG ; DW SECTORS PER TRACK ; DB BLOCK SHIFT FACTOR ; DB BLOCK MASK ; DB EXTENT MASK ; DW # OF BLOCKS - 1 ; DW # OF DIRECTORY ENTRIES - 1 ; DW AL1*256+AL0 ; DW LENGTH OF CHECKSUM VECTOR ; DW # OF SYSTEM TRACKS ; F207TBL RB 0 ;5 1/4" DOUBLE DENSITY (8X512)/SINGLE SIDED/48 TPI DB DPEDD,4,8,0 DW 32 DB 3,7,0 DW 151,127,00F0H,32,2 F207TBLL EQU OFFSET $ - OFFSET F207TBL ;5 1/4" DOUBLE DENSITY (8X512)/DOUBLE SIDED/48 TPI DB DPEDD+DPE2S,4,16,0 DW 32 DB 4,15,1 DW 155,255,00F0H,64,2 ;5 1/4" DOUBLE DENSITY (8X512)/SINGLE SIDED/96 TPI DB DPEDD,4,16,DPE96TM DW 32 DB 4,15,1 DW 155,127,00C0H,32,2 ;5 1/4" DOUBLE DENSITY (8X512)/DOUBLE SIDED/96 TPI DB DPEDD+DPE2S,4,16,DPE96TM DW 32 DB 4,15,0 DW 315,255,00F0H,64,2 ;8" SINGLE DENSITY / SINGLE SIDED DB 0,1,8,0 DW 26 DB 3,7,0 DW 242,63 DB 0C0H,0 DW 16,2 ;8" SINGLE DENSITY / DOUBLE SIDED DB DPE2S,1,16,0 DW 26 DB 4,15,1 DW 246,127 DB 0C0H,0 DW 32,2 ;8" DOUBLE DENSITY / SINGLE SIDED DB DPEDD,2,16,0 DW 52 DB 4,15,1 DW 242,127 DB 0C0H,0 DW 32,2 ;8" DOUBLE DENSITY / DOUBLE SIDED DB DPEDD+DPE2S,2,16,0 DW 52 DB 4,15,0 DW 493,255 DB 0F0H,0 DW 64,2 EJECT CSEG $ ;** F217 - FORMAT 217 ; ; FORMATTING A Z217 PARTITION CONSISTS OF WRITING 0E5H BYTES THROUGH OUT ; THE SYSTEM TRACK(S) AND THE DIRECTORY. ; F217: MOV CL,SGUSR ;GET CURRENT USER CODE MOV DL,0FFH INT BDOSE MOV F217UC,AL MOV CL,SGUSR ;RESET USER CODE TO 31 MOV DL,15 ; TO HIDE FILE 'BADBLOCK.SYS' INT BDOSE TEST DRTYPE,DPEASGN ;Q. PARTITION ASSIGNED ; JZ F21799 ; BR IF NOT JNZ $+5 JMP F21799 MOV AL,DRIVID ;INFORM USER MOV FPARTD,AL MOV CL,PRCONB LEA DX,FMTPART INT BDOSE CMP NOQFLG,0 ;Q. SHOULD I AS IF READY JNE F2171 ; BR IF NO MOV CL,PRCONB ;ASK IF READY LEA DX,PROMPT1 INT BDOSE MOV CL,RDCON INT BDOSE CMP AL,CR ;Q. ; JNE F21798 ; ABORT IF NOT JE $+5 JMP F21798 F2171: CALL FCBD ;CLEAR BIOS BUFFERS FOR DRIVE CALL F21780 ;FILL IN DPB & CALC VALUES ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 ;* COMPUTE # CP/M RECORDS TO CLEAR. ; (# CP/M RECORDS) = (# DIRECTORY ALLOCATION BLOCKS) SHL (BSH) + ; (# RECORDS FOR SYSTEM TRACK(S)) LES BX,DWORD PTR DPBPTR ;GET # ALLOCATION BLOCKS FOR DIRECTORY MOV AX,0 MOV DH,ES: DPBAL0[BX] MOV DL,ES: DPBAL1[BX] F2172: SHL DX,1 JNC F2172A INC AX JMPS F2172 F2172A: MOV F217DAB,AX ;SAVE # ALLOCATION BLOCKS MOV CL,ES: DPBBSH[BX] ;GET BLOCK SHIFT FACTOR SHL AX,CL ;(DIRECTORY AB'S) SHL (BSH)  ADD AX,WINST*WIRPT ;ADD # CP/M RECORDS FOR SYSTEM TRACK(S) MOV F217C1,AX ;* WRITE 0E5H TO ALL SECTORS TO BE CLEARED MOV CX,128 ;FILL SECTOR BUFFER WITH 0E5H MOV DI,0 MOV ES,BUFFER MOV AL,0E5H CLD REP STOSB MOV CX,0 ;SET DMA OFFSET CALL FSETDMA MOV CX,BUFFER ;SET DMA SEGMENT CALL FSETDMAS MOV F217TRK,0 ;INIT TRACK # MOV F217SEC,1 ;INIT SECTOR # F21710: MOV CX,F217TRK ;SET TRACK # CALL FSETTRK MOV CX,F217SEC ;SET SECTOR # CALL FSETSEC MOV CL,BWRNOR ;WRITE SECTOR CALL FWRITE CMP AL,0 ;Q. ERROR ; JNE F21799 ; BR IF ERROR JE $+5 JMP F21799 CMP F217SEC,WIRPT ;Q. JUST WROTE LAST SECTOR OF TRACK JNE F21712 ; BR IF NO MOV F217SEC,0 ;RESET SECTOR # INC F217TRK ;INCREMENT TRACK # F21712: INC F217SEC ;BUMP SECTOR # DEC F217C1 ;LOOP JNZ F21710 ;* WRITE LABEL TO 1ST SECTOR OF DISK CALL WRLAB ; JC F21799 ;BR IF ERROR JNC $+5 JMP F21799 ;* BUILD A FILE WITH THE BAD SECTORS OF THIS PARTITION ALLOCATED ; TO THIS FILE SO THEY CAN'T BE USED. MOV AL,DRIVID ;GET DRIVE SUB AL,'A'-1 ;CONVERT TO 1-N MOV F217FCB+OFFSET FCBDN,AL ;PLACE IN FCB CALL F217RDB ;READ IN BAD SECTOR TABLE ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 MOV F217LAB,0 ;INIT LAST ALLOCATION BLOCK MARKED BAD MOV F217C2,0 ;INIT ALLOCATION BLOCK COUNTER F2175A: CALL F21750 ;GET NEXT ENTRY IN TABLE JZ F2175C ; BR IF NO MORE ENTRIES SUB AX,F217LB ;Q. SECTOR # BEFORE START OF PARTITION JC F2175A ; BR IF YES SUB AX,WINSYS ;Q. SECTOR # WITHIN SYSTEM TRACK(S) ; JC F21799 ; BR IF YES JNC $+5 JMP F21799 LES BX,DWORD PTR DPBPTR ;CALCULATE ALLOCATION BLOCK # XOR CH,CH ; AB = (AX) SHR (BSH-2) MOV CL,ES:DPBBSH[BX] SUB CL,2 SHR AX,CL IF WICSZ NE 512 %: SECTOR SIZE NE 512 ENDIF CMP AX,F217DAB ;Q. BAD SECTOR WITHIN DIRECTORY ; JB F21799 ; BR IF YES JNB $+5 JMP F21799 CMP AX,ES:DPBDSM[BX] ;Q. CHECK AGAINST MAX BLOCK # JA F2175A ; BR IF PAST END OF PARTITION CMP AX,F217LAB ;Q. SAME AS LAST BAD BLOCK # JE F2175A ; BR IF YES MOV F217LAB,AX ;UPDATE 'F217LAB' ; ADD BAD BLOCK # TO DISK MAP FOR THE CURRENT DIRECTORY ENTRY. CMP F217C2,16 ;Q. MAP FULL JNE F2175B ; BR IF NOT PUSH AX ;SAVE ALLOCATION BLOCK # CALL F21760 ;WRITE DIRECTORY ENTRY TO DISK POP AX ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 MOV F217C2,0 ;ZERO MAP COUNTER F2175B: MOV BX,F217C2 ;PLACE BAD BLOCK # INTO MAP MOV WORD PTR F217MAP[BX],AX INC F217C2 ;BUMP MAP COUNTER LES BX,DWORD PTR DPBPTR ;CHECK DSM TO SEE IF SINGLE OR CMP ES: BYTE PTR DPBDSM+1[BX],0 ; DOUBLE BYTE MAP VALUES JE F2175A ; BR IF SINGLE (DSM <= 255) INC F217C2 JMPS F2175A ; DONE BUILDING DIRECTORY ENTRIES BAD SECTORS. F2175C: CALL F21760 ;WRITE DIRECTORY ENTRY ; JC F21799 ; BR IF ERROR JNC $+5 JMP F21799 OR F217FCB+OFFSET FCBRO,FCBROF ;SET ATTRIBUTES TO R/O & SYS OR F217FCB+OFFSET FCBSYS,FCBSYSF MOV CL,SFA LEA DX,F217FCB INT BDOSE ;* JMP F21798 ;* GET NEXT ENTRY FOR BAD SECTOR TABLE. ; ; ENTRY: (F217BSE)=TABLE POINTER ; EXIT: 'Z' 0=ENTRY PRESENT , 1=NO MORE ENTRIES ; (AX)=BAD SECTOR # ; USES: ALL ; F21750: MOV BX,F217BSE ;GET TABLE POINTER TO NEXT ENTRY MOV ES,BUFFER MOV AX,ES:[BX] ;GET LOW ORDER 16 BITS ADD F217BSE,3 ;UPDATE TABLE POINTER CMP AX,0 ;UPDATE ZERO FLAG RET ;* WRITE DIRECTORY ENTRY TO DISK. ; ; ENTRY: (F217C2)=MAP COUNTER ; (F217FCB)=DIRECTORY ENTRY ; EXIT: (F217C2)=MAP COUNTER ZEROED ; (F217FCB)=DIRECTORY ENTRY UPDATED FOR NEXT EXTENT ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; F21760: CMP F217C2,0 ;Q. MAP COUNTER = 0 JE F21763 ; BR IF YES -- DIR ENTRY IS EMPTY MOV CL,RDS ;RESET DISK SYSTEM INT BDOSE MOV CL,CREATE ;MAKE FILE FOR THIS ENTRY LEA DX,F217FCB INT BDOSE CMP AL,0FFH JE F21764 ; BR IF ERROR MOV CX,16 ;MOVE MAP TO FCB LEA SI,F217MAP LEA DI,F217FCB+OFFSET FCBDM F21761: MOV AL,[SI] MOV BYTE PTR [SI],0 MOV [DI],AL INC SI INC DI LOOP  F21761 LES BX,DWORD PTR DPBPTR ;SET EXTENT NUMBER BYTE MOV AL,F217FCB+OFFSET FCBEX ADD AL,ES:DPBEXM[BX] CMP AL,32 ;EXTENT NUMBER > MAX JB F21762 ; BR IF NOT SUB AL,32 ; MAKE EXTENT # MODULUS 32 INC F217FCB+OFFSET FCBRWF ; INC MODULE NUMBER F21762: MOV F217FCB+OFFSET FCBEX,AL MOV F217FCB+OFFSET FCBRC,128 ;SET RECORD COUNT TO FULL AND F217FCB+OFFSET FCBRWF,07FH ;CLEAR 'FILE WRITE FLAG' MOV CL,CLOSE ;CLOSE FILE LEA DX,F217FCB INT BDOSE CMP AL,0FFH JE F21764 ; BR IF ERROR INC F217FCB+OFFSET FCBEX ;SET EXTENT NUMBER FOR NEXT TIME MOV F217C2,0 ;CLEAR MAP COUNTER F21763: CLC ;INDICATE NO ERROR RET F21764: STC ;INDICATE ERROR RET ;* CALCULATE DPE HEATH EXTENSIONS AND DISK PARAMETER BLOCK VALUES F21780: ; CALCULATE # SECTORS WITHIN PARTITION. LES BX,DWORD PTR DPEPTR ;GET LAST SECTOR # + 1 MOV AX,ES: WORD PTR DPEUPB[BX] INC AX MOV DX,ES: WORD PTR DPETRK[BX] ;GET BEGINNING SECTOR # MOV F217LB,DX SUB AX,DX ;# SECTORS WITHIN PARTITION CMP AX,WIMIN ;Q. >= MINIMUM ALLOWABLE JAE F21781 ; BR IF YES MOV CL,PRCONB LEA DX,MINMSG INT BDOSE STC JMP F21789 F21781: CMP AX,WIMAX ;Q. <= MAXIMUM USEABLE JBE F21782 ; BR IF YES MOV CL,PRCONB ;ISSUE WARNING MESSAGE LEA DX,MAXMSG INT BDOSE MOV AX,WIMAX ;ONLY ALLOW MAXIMUM USABLE F21782: MOV F217NS,AX ;SAVE # SECTORS WITHIN PARTITION ; SEARCH PARAMETER TABLE TO FIND ENTRY THAT THE PARTITION'S # USEABLE ; SECTORS >= TABLE ENTRY'S # SECTORS. LEA BX,F217TBL ;GET TABLE POINTER F21783: CMP AX,F217TNS[BX] ;Q. COMPARE JAE F21784 ; BR IF >= ADD BX,F217TBLL ;BUMP TO NEXT TABLE ENTRY JMPS F21783 ; PLACE INFO INTO THE HEATH EXTENSION AREA OF THE DRIVES'S ; DISK PARAMETER ENTRIES TABLE. F21784: LES DI,DWORD PTR DPEPTR ;GET DPE POINTER MOV AL,F217TRA[BX] ;CP/M RECORDS PER ALLOCATION BLOCK MOV ES:DPERPAB[DI],AL ; PLACE INFO INTO THE DRIVE'S DISK PARAMETER BLOCK. LES DI,DWORD PTR DPBPTR ;GET DPB POINTER MOV ES:DPBSPT[DI],WIRPT ;CP/M RECORDS PER TRACK MOV AL,F217TBS[BX] ;BLOCK SHIFT FACTOR MOV ES:DPBBSH[DI],AL MOV AL,F217TBM[BX] ;BLOCK MASK MOV ES:DPBBLM[DI],AL MOV AL,F217TEX[BX] ;EXTENT MASK MOV ES:DPBEXM[DI],AL MOV AX,F217TDE[BX] ;# DIRECTORY ENTRIES - 1 MOV ES:DPBDRM[DI],AX MOV AL,F217TA0[BX] ;AL0 MOV ES:DPBAL0[DI],AL MOV AL,F217TA1[BX] ;AL1 MOV ES:DPBAL1[DI],AL MOV ES:DPBCKS[DI],0 ;CHECKSUM VECTOR LENGTH MOV ES:DPBOFF[DI],WINST ;# OF SYSTEM TRACKS ; CALCULATE DISK PARAMETER BLOCK 'DSM' VALUE. ; DSM = ( [# USEABLE SECTORS] - [# SYSTEM SECTORS] ) / ; [# SECTORS PER ALLOCATION BLOCK] - 1 MOV AX,F217NS SUB AX,WINSYS LES BX,DWORD PTR DPBPTR MOV CL,ES:DPBBSH[BX] SUB CL,2 SHR AX,CL IF WICSZ NE 512 %: CELL SIZE IS NOT 512 ENDIF DEC AX MOV ES:DPBDSM[BX],AX ; CLC ;INDICATE NO ERROR F21789: RET ;* NO ERROR F21798: CLC JMPS F217100 ;* ERROR F21799: STC ;* DONE FORMATTING Z217 PARTITION F217100: PUSHF MOV CL,SGUSR ;RESTORE USER CODE MOV DL,F217UC INT BDOSE CALL FCBD ;CLEAR BIOS BUFFERS POPF RET ;* READ IN BAD SECTOR TABLE F217RDB: CALL FCBD ;CLEAR BUFFERS LES BX,DWORD PTR DPEPTR ;INDICATE DO LOGICAL I/O OR ES:DPEFLAG[BX],DPELSIO MOV F217BSE,0 ;READ SBC MOV F217SEC,1 MOV F217C2,WIRPS F217RDB1: MOV CX,0 ;READ NEXT SECTOR OF SBC MOV DX,F217SEC MOV DI,F217BSE MOV ES,BUFFER CALL F217RD ; JC F217RDB9 ; BR IF ERROR JNC $+5 JMP F217RDB9 ADD F217BSE,128 INC F217SEC DEC F217C2 JNZ F217RDB1 MOV BX,0 ;CHECK CHECKSUM MOV ES,BUFFER MOV CX,WICSZ MOV DX,0 XCHG DX,ES:SBCCRC CALL F217CS STC ; JNE F217RDB9 ; BR IF NOT CORRECT JE $+5 JMP F217RDB9 MOV ES,BUFFER ;LOGICAL SECTOR # OF BAD SECTOR TABLE MOV AX,ES: WORD PTR SBCBSA ; COPY A MOV F217BSA,AX MOV AX,ES: SBCCBA ;BAD SECTOR TABLE COPY A CHECKSUM MOV F217CBA,AX MOV AX,ES: WORD PTR SBCBSB ;LOGICAL SECTOR # OF BAD SECTOR TABLE MOV F217BSB,AX ; COPY B MOV AX,ES: SBCC BB ;BAD SECTOR TABLE COPY B CHECKSUM MOV F217CBB,AX MOV F217CB,0 ;CLEAR USE COPY B FLAG F217RDB2: MOV AX,F217BSA ;GET LOG SEC # OF BAD SECTOR TABLE XOR DX,DX ;COMPUTE TRACK # MOV CX,WINSPT DIV CX MOV F217TRK,AX MOV AL,WIRPS ;COMPUTE CP/M SECTOR # = PHYSICAL MUL DL ; SECTOR # * CP/M RECORDS PER INC AX ; PHYSICAL SECTOR + 1 MOV F217SEC,AX MOV F217BSE,0 ;SET BUFFER ADDRESS MOV F217C2,WIRPS*2 ;ASSUME TABLE FIT IN 2 PHYSICAL SECTORS F217RDB3: MOV CX,F217TRK ;GET TRACK # MOV DX,F217SEC ;GET SECTOR # MOV DI,F217BSE ;GET BUFFER FWA MOV ES,BUFFER CALL F217RD ;READ 128 BYTES JC F217RDB5 ; BR IF ERROR CMP F217SEC,WIRPT ;Q. END OF TRACK JNE F217RDB4 ; BR IF NOT INC F217TRK ;BUMP TRACK # MOV F217SEC,0 F217RDB4: INC F217SEC ;BUMP SECTOR # ADD F217BSE,128 ;BUMP BUFFER ADDRESS DEC F217C2 ;LOOP AND READ JNZ F217RDB3 MOV BX,0 ;CHECK CHECKSUM MOV ES,BUFFER MOV CX,WIRPS*2 MOV DX,F217CBA CALL F217CS JE F217RDB6 F217RDB5: CMP F217CB,0 ;Q. ALREADY TRYING FOR COPY B STC JNE F217RDB9 ; BR IF YES MOV F217CB,1 ;SET UP TO TRY FOR COPY B MOV AX,F217BSB MOV F217BSA,AX MOV AX,F217CBB MOV F217CBA,AX JMP F217RDB2 F217RDB6: MOV F217BSE,0 ;INIT BAD SECTOR TABLE ENTRY POINTER CLC ;INDICATE NO ERROR F217RDB9: PUSHF ;SAVE CARRY FLAG (ERROR INDICATOR) LES BX,DWORD PTR DPEPTR ;TURN OFF DOING LOGICAL SECTOR I/O AND ES:DPEFLAG[BX],NOT DPELSIO CALL FCBD ;CLEAR BIOS BUFFERS POPF ;RETRIEVE ERROR INDICATOR RET ;* CALCULATE CHECK SUM AND CHECK IT ; ; ENTRY: (BX),(ES)=RECORD ; (CX)=SIZE ; (DX)=CHECKSUM ; EXIT: PSW/Z 0=ERROR , 1=OK ; USES: AX,BX,CX ; F217CS: MOV AX,0 F217CS1: ADD AL,ES:[BX] ADC AH,0 INC BX LOOP F217CS1 NOT AX CMP AX,DX RET ;* READ CP/M SECTOR FROM DISK ; ; ENTRY: (CX)=TRACK # ; (DX)=CP/M SECTOR # (1 TO SPT) ; (DI)=BUFFER FWA OFFSET ; (ES)=BUFFER FWA SEGMENT ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; F217RD: PUSH ES PUSH DI PUSH DX CALL FSETTRK ;SET TRACK POP CX CALL FSETSEC ;SET SECTOR POP CX ;SET DMA OFFSET CALL FSETDMA POP CX ;SET DMA SEGMENT CALL FSETDMAS CALL FREAD ;READ SECTOR CMP AL,0 ;Q. ERROR JE F217RD1 ; BR IF NOT STC ;INDICATE ERROR F217RD1: RET EJECT DSEG $ ;* PARAMETER TABLE CONTAINING ; 1) HEATH EXTENSION VALUES ; 2) DISK PARAMETER BLOCK VALUES ; ; FORMAT OF TABLE: ; BYTE #  DESCRIPTION ; - -@ ; 0-1 # SECTORS -- THIS ENTRY IS USED IF PARTITION'S ;  # USEABLE SECTORS >= ;  2 % CP/M RECORDS PER ALLOCATION BLOCK ;  3  BLOCK SHIFT FACTOR ;  4  BLOCK MASK ;  5 8 EXTENT MASK ; 6-7 # OF DIRECTORY ENTRIES - 1 ;  8  AL0 ;  9 AL1 ; F217TBL RB 0 F217TNS EQU 0 F217TRA EQU 2 F217TBS EQU 3 F217TBM EQU 4 F217TEX EQU 5 F217TDE EQU 6 F217TA0 EQU 8 F217TA1 EQU 9 DW 1024/WICSZ*4*1024+WINSYS+1 ;4 MEG < X <= 8 MEG DB 32,5,31,1 DW 1023 DB 0FFH,000H F217TBLL EQU OFFSET $ - OFFSET F217TBL ;TABLE ENTRY LENGTH DW 1024/WICSZ*1*1024+WINSYS+1 ;1 MEG < X <= 4 MEG DB 16,4,15,0 DW 511 DB 0FFH,000H DW 1024/WICSZ*512+WINSYS+1 ;512K < X <= 1 MEG DB 16,4,15,0 DW 255 DB 0F0H,000H DW 1024/WICSZ*256+WINSYS+1 ;256K < X <= 512K DB 16,4,15,1 DW 127 DB 0C0H,000H DW WIMIN ;MINIMUM <= X <= 256K DB 8,3,7,0 DW 63 DB 0C0H,000H FMTPART DB CR,LF,CR,LF,'Will format partition assigned to drive ' FPARTD DB '?:',CR,LF,CPMEOM MINMSG DB CR,LF,BELL,'PARTION IS SMALLER THAN MINIMUM ALLOWABLE ' DB 'SIZE',CR,LF,CPMEOM MAXMSG DB CR,LF,BELL,'PARTITION IS LARGER THAN CP/M MAXIMUM SIZE' DB ' -- ONLY 8 MEG USEABLE',CR,LF,CPMEOM F217NS RW 1 ;# USEABLE SECTORS F217TRK RW 1 ;TRACK # F217SEC RW 1 ;SECTOR # F217DAB RW 1 ;# DIRECTORY ALLOCATION BLOCKS F217C1 RW 1 ;LOOP COUNTER F217C2 RW 1 ;COUNTER F217BSE RW 1 ;BAD SECTOR TA BLE POINTER F217LAB RW 1 ;LAST ALLOCATION BLOCK MARKED BAD F217LB RW 1 ;PARTITION LOWER BOUND F217UC RB 1 ;USER CODE F217BSA RW 1 ;LOG SEC # BAD SECTOR TABLE COPY A F217CBA RW 1 ;BAD SECTOR TABLE COPY A CHECKSUM F217BSB RW 1 ;LOG SEC # BAD SECTOR TABLE COPY B F217CBB RW 1 ;BAD SECTOR TABLE COPY B CHECKSUM F217CB RB 1 ;USE COPY B FLAG F217FCB DB 0,'BADBLOCKSYS',0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 F217MAP DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 EJECT CSEG $ ;** WKIND -- DETERMINES DRIVE TYPE AND SELECTS DRIVE ; ; ENTRY: (AL)=DRIVE NAME ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; WKIND: SUB AL,'A' ;CONVERT TO CP/M DRIVE # MOV CL,AL CALL FSETDSK ;ATTEMPT TO SELECT DRIVE CMP BX,0 ;Q. SELECT ERROR JE WKIND9 ; BR IF ERROR MOV DPEPTR,BX ;SAVE POINTER TO DPE MOV ES,OSDS MOV DPEPTR+2,ES MOV AX,ES:DPEDPB[BX] ;DPB MOV DPBPTR,AX MOV DPBPTR+2,ES MOV AL,ES:DPEFLAG[BX] ;FLAG MOV DRTYPE,AL MOV AL,ES:DPEUNIT[BX] ;UNIT SELECT MOV AIOUNI,AL MOV AL,ES:DPEFLG2[BX] ;FLAG2 MOV FLAG2,AL CLC ;INDICATE NO ERROR RET WKIND9: STC ;INDICATE ERROR RET ;** FSETDSK - GETS DISK TABLE POINTER IN (BX)/(ES) ; ; ENTRY: (CL)=CP/M DRIVE # ; EXIT: (BX)=ADDRESS OFFSET (0=ERROR) ; USES: ALL ; FSETDSK: MOV DBIOSF,SETDSK MOV DL,1 JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETTRK - SET CP/M TRACK # ; ; ENTRY: (CX)=TRACK # ; EXIT: NONE ; USES: ALL ; FSETTRK: MOV DBIOSF,SETTRK JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETSEC - SET CP/M SECTOR # ; ; ENTRY: (CX)=SECTOR # ; EXIT: NONE ; USES: ALL ; FSETSEC: MOV DBIOSF,SETSEC JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETDMA - SET CP/M DMA OFFSET ; ; ENTRY: (CX)=DMA OFFSET ; EXIT: NONE ; USES: ALL ; FSETDMA: MOV DBIOSF,SDMA JMPS DOBIOS ;RETURN THRU DOBIOS ;** FSETDMAS - SET CP/M DMA SEGMENT ; ; ENTRY: (CX)=DMA SEGMENT ; EXIT: NONE ; USES: ALL ; FSETDMAS: MOV DBIOSF,SETDMAB JMPS DOBIOS ;RETURN THRU DOBIOS ;** FREAD - READ CP/M SECTOR ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FREAD: MOV DBIOSF,BREAD JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWRITE - WRITE CP/M SECTOR ; ; ENTRY: (CL)=WRITE MODE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FWRITE: MOV DBIOSF,BWRITE JMPS DOBIOS ;RETURN THRU DOBIOS ;** FFORMAT - FORMAT DISK ; ; ENTRY: (CL)=VERIFY FLAG ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FFORMAT: MOV DBIOSF,BFMT JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWRTRK - WRITE TRACK ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; USES: ALL ; FWRTRK: MOV DBIOSF,BWRTRK JMPS DOBIOS ;RETURN THRU DOBIOS ;** FWPC - WRITE PROTECT CHECK ; ; ENTRY: NONE ; EXIT: (AL)=WRITE PROTECT STATUS (0=NO , 1=YES) ; USES: ALL ; FWPC: MOV DBIOSF,BWPC JMPS DOBIOS ;RETURN THRU DOBIOS ;** FCBD - CLEAR BUFFER FOR DRIVE ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; FCBD: MOV DBIOSF,BCBD JMPS DOBIOS ;RETURN THRU DOBIOS ;** FGBT - GET ADDRESS OF BIOS TABLES ; ; ENTRY: NONE ; EXIT: (BX)=ADDRESS OFFSET ; (ES)=ADDRESS SEGMENT ; USES: ALL ; FGBT: MOV DBIOSF,BGBT ;** DOBIOS - DIRECT BIOS CALL ; ; ENTRY: (CX) & (DX) ; EXIT: WHATEVER IS RETURNED BY BIOS ; USES: ALL ; DOBIOS: MOV DBIOSCX,CX MOV DBIOSDX,DX MOV CL,DBIOS LEA DX,DBIOST INT BDOSE RET EJECT ;** DISPATCH - CALL APPROPRIATE FORMATTING ROUTINE ; DISPATCH: XOR BH,BH MOV BL,DRTYPE MOV CL,5 SHR BX,CL SHL BX,1 CMP FMTRTN[BX],0 JE DISPATCH1 JMP FMTRTN[BX] DISPATCH1: RET ;** TOUPPER - CONVERT TO UPPER CASE ; ; ENTRY: (AL)=VALUE ; EXIT: (AL)=VALUE CONVERTED TO UPPERCASE ; USES: AL ; TOUPPER: CMP AL,'a' JB TOUPPER1 CMP AL,'z' JA TOUPPER1 SUB AL,'a'-'A' TOUPPER1: RET ;** WRLAB - FORM LABEL AND WRITE IT TO 1ST SECTOR OF DISK ; ; ENTRY: NONE ; EXIT: 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; WRLAB: MOV CX,128 ;CLEAR 128 BYTES OF BUFFER TO 0E5H M OV DI,0 MOV ES,BUFFER CLD MOV AL,0E5H REP STOSB MOV ES: BYTE PTR .LABTYP,LABVER ;INSERT CURRENT FORM # ; MOVE HEATH EXTENSIONS TO LABEL PUSH DS MOV DI,LABHTH LDS SI,DWORD PTR DPEPTR ADD SI,OFFSET DPEHTH MOV CX,DPEHL REP MOVSB POP DS ; MOVE DPB TO LABEL PUSH DS MOV DI,LABDPB LDS SI,DWORD PTR DPBPTR MOV CX,DPBL REP MOVSB POP DS ; CALCULATE CHECKSUM FOR LABEL XOR AL,AL MOV BX,LABEL MOV CX,LABLEN-1 WRLAB1: ADD AL,ES:[BX] INC BX LOOP WRLAB1 NOT AL MOV ES:[BX],AL ; WRITE LABEL TO DISK MOV CX,0 CALL FSETTRK MOV CX,1 CALL FSETSEC MOV CX,0 CALL FSETDMA MOV CX,BUFFER CALL FSETDMAS MOV CL,BWRDIR CALL FWRITE OR AL,AL ;Q. ERROR JZ WRLAB2 ; BR IF NOT STC ;INDICATE ERROR ; WRLAB2: RET EJECT ;** CLINT - COMMAND LINE INTERPRETER ; ; ENTRY: (TBUFF)=COUNT ; TBUFF+1=ADDRESS OF COMMAND LINE ; EXIT: VALUES ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; CLINT: MOV COMLIN,1 ;INDICATE COMMAND LINE PRESENT MOV CL,TBUFF ;COUNT LEA SI,TBUFF+1 ;ADDR OF START OF STRING CALL CSCAN ;FIND DRIVE NAME CMP AL,TNAME ;Q. DRIVE NAME JNE RDOPT9 ; BR IF NOT CMP CH,2 ;Q. TOKEN LENGTH = 2 JNE RDOPT9 ; BR IF NOT CMP BYTE PTR 1[DI],':' ;Q. 2ND CHARACTER = ':' JNE RDOPT9 ; BR IF YES MOV AL,[DI] ;SAVE DRIVE NAME MOV DRIVID,AL ;* RDOPT - READ OPTIONS ; ; ENTRY: (CL)=COMMAND LINE COUNT ; (SI)=COMMAND LINE POINTER ; EXIT: VALUES ; 'CY' 0=NO ERROR , 1=ERROR ; USES: ALL ; CALL CSCAN ;GET NEXT TOKEN CMP AL,TEOL ;Q. EOL JE RDOPT90 ; BR IF YES CMP AL,TLBR ;Q. '[' JNE RDOPT9 ; BR IF NOT ; MAIN LOOP RDOPT0: CALL CSCAN ;GET OPTION CMP AL,TNAME ;Q. VALID JNE RDOPT9 ; BR IF NOT ; DECODE SECTION RDOPT1: CMP CH,1 ;Q. TOKEN SIZE = 1 JNE RDOPT2 ; BR IF NOT MOV AL,[DI] ;GET TOKEN CMP AL,'F' ;Q. FAST JNE RDOPT1A ; BR IF NOT MOV FAST,1 ;SET FAST FLAG JMPS RDOPT6 RDOPT1A: CMP AL,'N' ;Q. NO QUERY JNE RDOPT10 ; BR IF NOT MOV NOQFLG,1 ;SET FLAG JMPS RDOPT6 RDOPT2: CMP CH,2 ;Q. TOKEN SIZE = 2 JNE RDOPT10 ; BR IF NOT MOV AX,[DI] ;GET TOKEN XCHG AL,AH CMP AX,'DD' ;Q. DOUBLE DENSITY JE RDOPT2B ; BR IF YES CMP AX,'SD' ;Q. SINGLE DENSITY JNE RDOPT2C ; BR IF NOT RDOPT2B: MOV CLIDENS,AH JMPS RDOPT6 RDOPT2C: CMP AX,'1S' ;Q. SINGLE SIDED JE RDOPT2D ; BR IF YES CMP AX,'2S' ;Q. DOUBLE SIDED JNE RDOPT2E ; BR IF NOT RDOPT2D: MOV CLISIDS,AH JMPS RDOPT6 RDOPT2E: CMP AX,'D0' ;Q. TRACK 0 DOUBLE DENSITY JNE RDOPT10 ; BR IF NOT MOV CLID0,1 ;SET FLAG ; END OF OPTION DECODE, GET NEXT OPTION RDOPT6: CALL CSCAN ;LOOK FOR MORE OPTIONS CMP AL,TRBR ;Q. ']' JE RDOPT90 ; BR IF YES CMP AL,TCOMMA ;Q; ',' JE RDOPT0 ; BR IF YES ; SYNTAX ERROR RDOPT9: MOV CL,PRCONB LEA DX,SYNMSG INT BDOSE STC JMPS RDOPT90 ; ILLEGAL OPTION RDOPT10: MOV CL,PRCONB LEA DX,OPTMSG INT BDOSE STC ; RDOPT90: RET ;* CSCAN - SCANNER FOR CP/M COMMAND LINES ; ; CSCAN IS CALLED TO GET THE NEXT TOKEN FROM A CP/M ; COMMAND LINE. ; ; ENTRY: (CL)=COUNT ; (SI)=COMMAND LINE POINTER ; EXIT: (CL)=UPDATED COUNT ; (SI)=UPDATED COMMAND LINE POINTER ; (AL)=TOKEN TYPE ; (DI)=ADDRESS OF TOKEN ; (CH)=LENGTH OF TOKEN ; USES: ALL ; CSCAN: MOV DH,0 ;STATE = 0 MOV CH,0 ;TOKEN SIZE = 0 ; MAIN LOOP CSC00: MOV DL,0 ;ASSUME CLASS 0 CMP CL,0 ;Q. BYTES LEFT JE CSC02 ; BR IF NOT ; COMPUTE CHARACTER CLASS MOV AL,[SI] ;GET BYTE FROM STRING AND AL,07FH ;STRIP MS BIT CALL TOUPPER ;UPC XLATE MOV [SI],AL LEA BX,CSCCLT ;TABLE LOOKUP FOR CLASS XLAT AL MOV DL,AL ;SAVE CLASS ; COMPUTE INDEX FOR SCAN TABLE ENTRY GIVEN STATE & CLASS ; = 2*(STATE*NCLASS+CLASS) CSC02: MOV AL,CSCNCL MUL DH ADD AL,DL ADC AH,0 SHL AX,1 MOV BX,AX ; DECODE AND PERFORM ACTION TEST CSCSNT[BX],CSCACS ;Q. SET TOKEN START JZ CSC04 ; BR IF NOT MOV DI,SI CSC04: TEST CSCSNT[BX],CSCACA ;Q. INC TOKEN SIZE JZ CSC05 ; BR IF NOT INC CH CSC05: TEST CSCSNT[BX],CSCACI ;Q. INC STRING POINTER JZ CSC06 ; BR IF NOT INC SI DEC CL CSC06: TEST CSCSNT[BX],CSCACR ;Q. RETURN TRANSITION JNZ CSC07 ; BR IF YES ; GO TO NEXT STATE TRANSITION MOV DH,CSCSNT+1[BX] ;GET NEXT STATE JMPS CSC00 ; RETURN ACTION CSC07: MOV AL,CSCSNT+1[BX] ;GET TOKEN TYPE RET DSEG $ COMLIN DB 0 ;COMMAND LINE FLAG NOQFLG DB 0 ;NO QUERY FLAG DRIVID DB ' ' ;COMMAND LINE DIRVE ID CLID0 DB 0 ;TRACK 0 DOUBLE DENSITY FLAG CLIDENS DB 'D' ;COMMAND STRING DENSITY RESULT CLISIDS DB '2' ;COMMAND STRING SIDES RESULT FAST DB 0 ;FAST FLAG SYNMSG DB CR,LF,BELL,'Illegal Command Syntax',CR,LF,CPMEOM OPTMSG DB CR,LF,BELL,'Illegal Format Option',CR,LF,CPMEOM ; DEFINE CONSTANTS AND TABLES TNAME EQU 1 ; Name token TEQUAL EQU 2 ; Equal sign token TLBR EQU 3 ; Left brace token TRBR EQU 4 ; Right brace token TCOMMA EQU 5 ; Comma token TEOL EQU 6 ; End-of-line token TILG EQU 7 ; Illegal type token CSCACR EQU 08H ; "RETURN" action CSCACG EQU 00H ; "GOTO" action CSCACS EQU 01H ; Set token start action CSCACA EQU 02H ; Increase token size action CSCACI EQU 04H ; Increase string ptr action CSCAMK EQU 01H ; Action mask CSCNST EQU 2 ; Number of states CSCNCL EQU 8 ; Number of character classes ; THE CHARACTER CLASSES AND THE CHARACTER CLASS TABLE CSCEOL EQU 0 ; End of line class CSCILG EQU 1 ; Illegal character class CSCEQU EQU 2 ; Equal sign class CSCLBR EQU 3 ; Left brace class CSCRBR EQU 4 ; Right brace class CSCBNK EQU 5 ; Blank/tab class CSCCOM EQU 6 ; Comma class CSCNAM EQU 7 ; Name class ; FOR EACH OF THE 128 CHARACTERS, DEFINE WHICH CLASS IN WHICH IT BELONGS CSCCLT DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 00-07 DB CSCILG,CSCBNK,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 08-15 DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 16-23 DB CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG,CSCILG ; 24-31 DB CSCBNK,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 32-39 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCCOM,CSCNAM,CSCNAM,CSCNAM ; 40-47 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 48-55 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCEQU,CSCNAM,CSCNAM ; 56-63 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 64-71 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 72-79 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 80-87 DB CSCNAM,CSCNAM,CSCNAM,CSCLBR,CSCNAM,CSCRBR,CSCNAM,CSCNAM ; 88-95 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 96-03 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 04-11 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 12-19 DB CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM,CSCNAM ; 20-27 ; THE SCANNER STATE TABLE CSCSNT DB CSCACS+CSCACA+CSCACI+CSCACR,TEOL ; CSCEOL DB CSCACS+CSCACA+CSCACI+CSCACR,TILG ; CSCILG DB CSCACS+CSCACA+CSCACI+CSCACR,TEQUAL ; CSCEQU DB CSCACS+CSCACA+CSCACI+CSCACR,TLBR ; CSCLBR DB CSCACS+CSCACA+CSCACI+CSCACR,TRBR ; CSCRBR DB CSCACI+CSCACG,0 ; CSCBNK DB CSCACS+CSCACA+CSCACI+CSCACR,TCOMMA ; CSCCOM DB CSCACS+CSCACA+CSCACI+CSCACG,1 ; CSCNAM DB CSCACR,TNAME ; CSCEOL DB CSCACR,TNAME ; CSCILG DB CSCACR,TNAME ; CSCEQU DB CSCACR,TNAME ; CSCLBR DB CSCACR,TNAME ; CSCRBR DB CSCACR,TNAME ; CSCBNK DB CSCACR,TNAME ; CSCCOM DB CSCACA+CSCACI+CSCACG,1 ; CSCNAM EJECT SIGNON DB CR,LF,'CP/M-86 Format Version ' IF (BREL/10) NE 0 DB BREL/10+'0' ENDIF DB (BREL MOD 10)+'0','.' DB REVSN/10+'0',(REVSN MOD 10)+'0',CR,LF DB 'Copyright (c) 1983, Zenith Data Systems Corp.' DB CR,LF,CPMEOM SIGNON1 DB CR,LF,'This program is used to initialize a disk.',CR,LF DB 'All information currently on the disk will be destroyed.' DB CR,LF,'Is that what you want? (Y/N): ',CPMEOM BADBIOS DB 'Incorrect version of the BIOS',CR,LF,CPMEOM NOMEM DB 'Not enough memory',CR,LF,CPMEOM WHICH DB CR,LF,CR,LF DB 'Which drive do you wish to use for this operation?' DB ': ',CPMEOM ERRMSG DB CR,LF,BELL,'Option not available',CR,LF,CPMEOM WDSDMSG DB CR,LF,CR,LF DB 'Which density? (S=single, D=double): ',CPMEOM WSMSG DB CR,LF,CR,LF DB 'Number of sides? (1=single, 2=double): ',CPMEOM DRMSG DB CR,LF,BELL,'Drive ' DRMSGA DB '? not available in current configuration.',CR,LF,CPMEOM PROMPT DB CR,LF,CR,LF DB 'Put the disk you wish to be formatted in drive ' PROMPTA DB '?.',CPMEOM PROMPT1 DB CR,LF DB 'Press RETURN to begin, anything else to abort.',CR,LF,CPMEOM AMWMSG DB CR,LF DB 'Do you have more disks to format? (Y/N): ',CPMEOM LVEMSG DB CR,LF DB 'Place a bootable disk in drive A: and press any ' DB 'character:',CPMEOM WPEMSG DB CR,LF DB 'Disk is write protected' BMSG DB CR,LF,BELL DB 'Unable to format this disk.',CR,LF,CPMEOM FMTRTN RW 0 DW 0 DW OFFSET F207 DW OFFSET F217 DW 0 DW 0 DW 0 DW 0 DW 0 SYSDSK DB 0 ;SYSTEM DISK INVOLVED MCB RB 0 ;MEMORY REQUEST CONTROL BLOCK BUFFER RW 1 DW 1024/16*12 RB 1 DENSITY RB 1 ;DENSITY TO BE USED SIDES RB 1 ;# SIDES DRTYPE RB 1 ;FLAG BYTE #1 AIOUNI RB 1 ;UNIT SELECT FLAG2 RB 1 ;FLAG BYTE #2 TRACK RW 1 ;TRACK COUNTER DSKTKS RW 1 ;NUMBER OF TRACKS DSKSPT RB 1 ;NUMBER OF PHYSICAL SECTORS PER TRACK OSDS RW 1 ;OS (DS) VALUE DPEPTR RW 2 ;DISK PARAMETER ENTRIES POINTER DPBPTR RW 2 ;DISK PARAMETER BLOCK POINTER DBIOST RB 0 ;DIRECT BIOS CALL PARAMETER LIST DBIOSF RB 1 DBIOSCX RW 1 DBIOSDX RW 1 RB 256 ;STACK STACK RB 0 EJECT ;* PATCH AREA FOR CODE SEGMENT CSEG $ PATCOD RB 127 DB 0 ;* PATCH AREA FOR DATA SEGMENT DSEG $ PATDAT RB 63 DB 0 END  TITLE 'Z207 CP/M-86 LOADER BIOS 07 JUL 83' ;*** ; ; THIS IS THE Z207 LOADER BIOS FOR CP/M-86. ; ; ASSUMPTIONS: ; 1. INTERRUPTS ARE DISABLED ; 2. BOOT DRIVE IS SELECTED AND MOTOR IS RUNNING ; ; ; RESTRICTED RIGHTS LEGEND ; - ; ; ^"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; FALSE EQU 0 TRUE EQU NOT FALSE DSEG INCLUDE ZMEMMAP.LIB INCLUDE CPM86SYS.LIB INCLUDE ZDPEDEF.LIB INCLUDE Z207DEF.LIB INCLUDE LABDEF.LIB INCLUDE ZMTR100.LIB INCLUDE ZPORTS.LIB INCLUDE DEF8259A.LIB INCLUDE EXTRAOPS.LIB ORG BDOSE*4 BDOSVEC RW 2 ;SWI VECTOR FOR BDOS ENTRY EJECT CSEG ORG LDCCP+3 CCPLOAD: ;** LOADER BIOS JUMP VECTORS ; ORG LDBIOS JMP CBOOTE ;COLD BOOT INIT JMP WBOOTE ;WARM BOOT JMP UNUSED ;CONSOLE STATUS JMP WBOOTE ;CONSOLE INPUT ; (ONLY REASON IS DISK I/O ERROR) JMP CONOUTE ;CONSOLE OUTPUT JMP UNUSED ;LIST OUTPUT JMP UNUSED ;PUNCH OUTPUT JMP UNUSED ;READER INPUT JMP HOMEE ;HOME HEAD JMP SETDSKE ;SET DISK JMP SETTRKE ;SET TRACK JMP SETSECE ;SET SECTOR JMP SETDMAE ;SET DMA OFFSET JMP READE ;READ CP/M SECTOR JMP UNUSED ;WRITE CP/M SECTOR JMP UNUSED ;LIST STATUS JMP SECTRNE ;SECTOR TRANSLATE JMP SDMABE ;SET DMA SEGMENT JMP UNUSED ;GET MRT OFFSET JMP UNUSED ;GET I/O MAPPING BYTE JMP UNUSED ;SET I/O MAPPING BYTE EJECT ;** COLD BOOT ENTRY ; CBOOTE: MOV AX,CS ;INIT SEGMENT REGISTERS MOV DS,AX MOV SS,AX LEA SP,STACK ; AND STACK MOV AL,0FFH ;INSURE INTERRUPTS CAN'T BOTHER ME OUT Z8259AM+OCW1,AL ; BY DISABLING 8259A'S OUT Z8259AS+OCW1,AL IN AL,FDTRK ;GET CURRENT TRACK FROM CONTROLLER MOV HSTTRK,AL XOR AX,AX ; SET UP BDOS VECTOR MOV ES,AX MOV ES: BDOSVEC,LDBDOS MOV ES: BDOSVEC+2,CS ; MOVE LABEL INFO TO LOCAL DPE AND DPB MOV SI,BOOTORG+LABHTH ;HEATH EXTENSIONS LEA DI,DPE+OFFSET DPEHTH PUSH DS PUSH ES POP DS ; DS=>0 POP ES ; ES=>LOADER MOV CX,DPEHL CLD REP MOVSB MOV SI,BOOTORG+LABDPB ;DPB LEA DI,DPB MOV CX,DPBL REP MOVSB PUSH ES POP DS ;DS=>LOADER ; MOV CL,0 ;DEFAULT DISK DRIVE JMP CCPLOAD ;BACK TO LOADER ;** WARM BOOT ENTRY ; WBOOTE: XOR AL,AL ;TURN OFF DRIVE OUT FDCON,AL HLT ;HALT MACHINE ;** CONSOLE OUTPUT ENTRY ; ; ENTRY: (CL)=CHARACTER TO BE OUTPUT ; EXIT: NONE ; USES: ALL ; CONOUTE: MOV MSAVSS,SS ;SAVE STACK MOV MSAVSP,SP MOV AX,DS ;SETUP LOCAL STACK MOV SS,AX LEA SP,MSTACK PUSHA MOV AL,CL CALLFI MTRSCRT,MTRSEG ;USE MONITOR I/O ROUTINE CALLFI MTRTINT,MTRSEG POPA MOV SS,MSAVSS ;RESTORE STACK MOV SP,MSAVSP RET ;** HOME HEAD ENTRY ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; HOMEE: MOV CX,0 JMPS SETTRKE ;** SET DISK DRIVE ENTRY ; ; ENTRY: (CL)=REQUESTED DRIVE ; EXIT: (BX)=ADDRESS OFFSET OF 'DPE' ; USES: ALL ; SETDSKE: XOR AX,AX ;ASSUME 5 1/4" DRIVE (NO XLATE TABLE) TEST DPE + OFFSET DPEUNIT,CONDS8 JZ SETDSKE1 ;BR IF 5 1/4" DRIVE LEA AX,XLATE1 ;ASSUME SINGLE DENSITY 8" TEST DPE + OFFSET DPEFLAG,DPEDD JZ SETDSKE1 ;BR IF SINGLE DENSITY LEA AX,XLATE2 ;ASSUME DOUBLE DENSITY 8" 26X256 CMP DPE + OFFSET DPERPS,256/128 JE SETDSKE1 ;BR IF 256 BYTE SECTORS XOR AX,AX ;USE NO XLATE TABLE SETDSKE1: MOV WORD PTR (DPE + OFFSET DPEXLT),AX LEA BX,DPE ;POINT TO DISK PARAMETER HEADER RET ;** SET TRACK ENTRY ; ; ENTRY: (CX)=TRACK # ; EXIT: NONE ; USES: ALL SETTRKE: MOV REQTRK,CX RET ;** SET SECTOR ENTRY ; ; ENTRY: (CX)=SECTOR # (IN RANGE 1 TO SPT) ; EXIT: NONE ; USES: ALL ; ; *** NONE *** ; IT IS ASSUMED ON ENTRY THAT THE SECTOR NUMBER IS IN THE RANGE 1 TO ; 'CP/M SECTORS PER TRACK'. THEREFORE, ONLY THE VALUE PASSED ; IN REGISTER CL IS USED. ; INTERNALLY THE BIOS WANTS SECTOR NUBMERS IN THE RANGE ; 0 TO SPT-1. THEREFORE, BEFORE SAVING THE SECTOR NUMBER, ; IT IS DECREMENTED. ; SETSECE: DEC CL ;PUT IN RANGE 0 TO SPT-1 XOR CH,CH ;ZERO HIGH ORDER BYTE MOV REQSEC,CX RET ;** SET DMA OFFSET ENTRY ; ; ENTRY: (CX)=DMA POINTER OFFSET ; EXIT: NONE ; USES: ALL ; SETDMAE: MOV DMAPTR,CX RET ;** SECTOR TRANSLATE ENTRY ; ; ENTRY: (CX)=LOGICAL SECTOR NUMBER (IN RANGE 0 TO SPT-1) ; (DX)=ADDRESS OF SECTOR TRANSLATE TABLE ; EXIT: (BX)=TRANSLATED CP/M SECTOR NUMBER (IN RANGE 1 TO SPT) ; USES: ALL ; SECTRNE: MOV BX,CX TEST DX,DX JZ SECTRNE1 ADD BX,DX MOV BL,[BX] XOR BH,BH JMPS SECTRNE2 SECTRNE1: INC BX SECTRNE2: RET ;** SET DMA SEGMENT ADDRESS ; ; ENTRY: (CX)=SEGMENT BASE FOR DMA READ OR WRITE OPERATIONS ; EXIT: NONE ; USES: ALL ; SDMABE: MOV DMASEG,CX RET UNUSED: XOR AL,AL XOR BX,BX RET EJECT WAIT EQU TRUE ;USE WAIT STATE I/O ;** READ CP/M SECTOR ENTRY ; ; ENTRY: NONE ; EXIT: (AL)=ERROR STATUS ; 0=NO ERROR , 1=ERROR ; USES: ALL ; READE: ; DETERMINE PHYSICAL TRACK, SIDE, AND SECTOR MOV AX,REQTRK ;ASSUME PHYSICAL TRACK = REQ TRACK MOV PHYTRK,AL MOV PHYSID,0 ;ASSUME SIDE 0 TEST DPE + OFFSET DPEFLAG,DPE2S JZ READE1 ;BR IF SINGLE SIDED MEDIA SHR PHYTRK,1 ;PHYSICAL TRACK = REQ TRACK / 2 JNC READE1 ;EVEN PHYSICAL TRACK ON SIDE 0 MOV PHYSID,FDFSS1 ;ODD PHYSICAL TRACK ON SIDE 1 READE1: MOV AX,REQSEC ;CALCULATE PHYSICAL SECTOR & DIV DPE + OFFSET DPERPS ; OFFSET MOV WORD PTR PHYSEC,AX ; CHECK IF PHYSICAL IS ALREADY IN HOST BUFFER MOV AL,PHYSID ;CHECK SIDE CMP AL,HSTSID JNE READE2 MOV AL,PHYTRK ;CHECK TRACK CMP AL,HSTTRK JNE READE2 MOV AL,PHYSEC ;CHECK SECTOR CMP AL,HSTSEC JE READE5 ; NEED TO READ PHYSICAL SECTOR INTO HOST BUFFER READE2: MOV AL,PHYTRK CMP AL,HSTTRK JE READE3 ;BR IF HEAD ALREADY AT DESIRED TRACK CALL SEEK ;SEEK TO DESIRED TRACK TEST DPE + OFFSET DPEFLAG,DPE48RO JZ READE2A ;BR IF NO NEED TO DOUBLE STEP MOV AL,HSTTRK ;DO DOUBLE STEP OUT FDTRK,AL CALL SEEK READE2A: MOV AL,PHYTRK ;REMEMBER WHERE HEAD IS NOW MOV HSTTRK,AL READE3: MOV AL,PHYSEC ;GET PHYSICAL SECTOR # MOV HSTSEC,AL ;REMEMBER IT INC AL ;PUT INTO RANGE 1 TO SPT OUT FDSEC,AL ;TELL CONTROLLER IF WAIT MOV AL,DPE + OFFSET DPEUNIT ;ENABLE WAIT STATE I/O OR AL,CONWE OUT FDCON,AL ENDIF MOV AL,PHYSID ;GET PHYSICAL SIDE # MOV HSTSID,AL ;REMEMBER IT OR AL,FDCRDS+FDFSLF+FDFDLF ;FORM READ COMMAND MOV CX,WORD PTR COUNT ;GET # BYTES PER SECTOR LEA DI,HSTBUF ;HOST BUFFER POINTER MOV DX,DS MOV ES,DX CLD OUT FDCMD,AL ;ISSUE COMMAND READE4: IF NOT WAIT IN AL,FDAS ;WAIT FOR DRQ OR IRQ TEST AL,ASDRQ+ASIRQ JZ READE4 ENDIF IN AL,FDDAT ;GET DATA STOSB ;STORE DATA INTO BUFFER LOOP READE4 ;LOOP FOR COUNT BYTES IF WAIT MOV AL,DPE + OFFSET DPEUNIT ;TURN OFF WAIT STATE I/O OUT FDCON,AL ENDIF CALL WIO1 ;WAIT FOR IRQ AND GET STATUS TEST AL,AL JNZ READEE ;BR IF ERROR ; MOVE CP/M RECORD FROM HOST BUFFER TO USER BUFFER READE5: MOV AL,PHYOFF ;CALC START OF CP/M RECORD MOV AH,128 MUL AH LEA SI,HSTBUF ADD SI,AX MOV CX,128 ;MOVE DATA LES DI,DWORD PTR DMAPTR CLD REP MOVSB ; RETURN INDICATING NO ERROR XOR AL,AL RET ; READ ERROR READEE: CMP AL,FDSRNF ;Q. RECORD NOT FOUND JNE READEE1 ; BR IF NOT TEST DPE + OFFSET DPEFLAG,DPE48RO JNZ READEE1 ;BR IF ALREADY DOUBLE STEPPING OR DPE + OFFSET DPEFLAG,DPE48RO ;SET DOUBLE STEP MOV AL,FDCRST+FDFHLB+FDFS30 ;RESTORE HEAD CALL WAITIO MOV HSTTRK,0 JMP READE2 ;RETRY READ READEE1: MOV AL,0FFH ;INDICATE ERROR RET ;* SEEK TO DESIRED TRACK SEEK: MOV AL,PHYTRK ;SET DESIRED TRACK OUT FDDAT,AL MOV AL,FDCSEK+FDFHLB+FDFS30 ;SEEK COMMAND ;* WAIT FOR I/O COMPLETION ; ; WAITIO -- ISSUE COMMAND AND WAIT ; WIO1 -- JUST WAIT, COMMAND HAS ALREADY BEEN ISSUED ; WAITIO: OUT FDCMD,AL ;ISSUE COMMAND WIO1: IN AL,FDAS ;WAIT FOR IRQ TEST AL,ASIRQ JZ WIO1 WIO2: IN AL,FDSTA ;WAIT FOR DRIVE READY TEST AL,FDSNRD JNZ WIO2 IN AL,FDSTA ;GET FINAL STATUS RET EJECT X EQU OFFSET $ DSEG ORG X DPE RB 0 ;DISK PARAMETER ENTRY TABLE DW 0 ; SECTOR TRANSLATE TABLE ADDRESS DW 0,0,0 ; SCRATCH DW DIRBUF ; DIRECTORY BUFFER DW DPB ; DISK PARAMETER BLOCK POINTER DW CSV ; CHECKSUM VECTOR POINTER DW ALV ; ALLOCATION VECTOR POINTER RB DPEHL ; HEATH EXTENSIONS IF (OFFSET $ - OFFSET DPE) NE DPEL %: DPE IS NOT CORRECT LENGTH ENDIF COUNT EQU DPE+OFFSET DPETRK HSTSID DB -1 ;CURRENT SIDE IN HOST BUFFER XLATE1 RB 0 ;8" SINGLE DENSITY SECTOR XLATE TABLE DB 1,7,13,19,25 DB 5,11,17,23 DB 3,9,15,21 DB 2,8,14,20,26 DB 6,12,18,24 DB 4,10,16,22 XLATE2 RB 0 ;8" DOUBLE DENSITY SECTOR XLATE TABLE DB 1,2,19,20,37,38 DB 3,4,21,22,39,40 DB 5,6,23,24,41,42 DB 7,8,25,26,43,44 DB 9,10,27,28,45,46 DB 11,12,29,30,47,48 DB 13,14,31,32,49,50 DB 15,16,33,34,51,52 DB 17,18,35,36 EJECT ; ; *** NOTE *** ; ; THERE ARE ONLY 52 CP/M SECTORS AVAILABLE FOR THE BOOT/LOADER CODE. ; THE LOADER CCP AND LOADER BDOS OCCUPY 36 SECTORS, LEAVING 16 CP/M ; SECTORS FOR THE BOOT CODE AND THE LOADER BIOS. THEREFORE, THE ; LOCATION COUNTER AT THIS POINT CANNOT BE GREATER THAN ; LDBIOS+LDBIOSL. ; IF (OFFSET $ - LDBIOS) GT LDBIOSL %: LOADER BIOS IS TOO LARGE ENDIF DIRBUF RB 128 ;DIRECTORY BUFFER DPB RB DPBL ;DISK PARAMETER BLOCK CSV RB 64 ;CHECKSUM VECTOR ALV RB 77 ;ALLOCATION VECTOR REQTRK RW 1 ;REQUESTED CP/M TRACK REQSEC RW 1 ;REQUESTED CP/M SECTOR DMAPTR RW 1 ;DMA OFFSET DMASEG RW 1 ;DMA SEGMENT IF (OFFSET DMASEG - OFFSET DMAPTR) NE 2 %: 'DMASEG' DOES NOT IMMEDIATELY FOLLOW 'DMAPTR' ENDIF PHYTRK RB 1 ;PHYSICAL TRACK PHYSID RB 1 ;PHYSICAL SIDE PHYSEC RB 1 ;PHYSICAL SECTOR PHYOFF RB 1 ;CP/M RECORD OFFSET IF (OFFSET PHYOFF - OFFSET PHYSEC) NE 1 %: 'PHYOFF' DOES NOT IMMEDIATELY FOLLOW 'PHYSEC' ENDIF HSTTRK RB 1 ;CURRENT TRACK IN HOST BUFFER HSTSEC RB 1 ;CURRECT SECTOR IN HOST BUFFER HSTBUF RB 1024 ;HOST DISK BUFFER RB 1024 ;STACK FOR MONITOR CALLS MSTACK RB 0 MSAVSS RW 1 MSAVSP RW 1 RB 64 ;LOCAL STACK FOR COLD BOOT STACK RB 0 END \ ;** ASCII CONTROL CHARACTER EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST CTLC EQU 003H ;CONTROL-C CTLQ EQU 011H ;CONTROL-Q CTLS EQU 013H ;CONTROL-S CTLZ EQU 01AH ;CONTROL-Z ACK EQU 006H ; BELL EQU 007H ;BELL CPMEOF EQU CTLZ ;ASCII FILE EOF MARK CPMEOM EQU '$' ;CP/M END-OF-MESSAGE SYMBOL CR EQU 00DH ;CARRIAGE RETURN ESC EQU 01BH ;ESCAPE ETX EQU CTLC ; DC1 EQU CTLQ ; DC3 EQU CTLS ; LF EQU 00AH ;LINE FEED NULL EQU 000H ;NULL TAB EQU 009H ;TAB  ;** DEFINITION OF SYSTEM CONTROL BLOCK IN THE BIOS FOR CP/M-86 ; ; * * * N O T E * * * ; ; IF THE BIOS IS ALTERED, THEN THIS FILE MUST ALSO BE UPDATED. ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; v"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST BREL EQU 1 ;RELEASE # FOR CURRENT BIOS $ ; USE THIS EQUATE IN USER PROGRAMS ; THAT WISH TO KNOW RELEASE # & ; THEY WERE ASSEMBLED FOR BRELA EQU (((BREL MOD 10)+'0') SHL 8) + (BREL/10+'0') BREVSN EQU 10 ;REVISION # BREVSNA EQU (((BREVSN MOD 10)+'0') SHL 8) + (BREVSN/10+'0') BMO EQU 09 ;DATE BDY EQU 26 BYR EQU 83 NDRIVES EQU 6 ;MAXIMUM NUMBER OF DRIVE TABLES ; AUTOCL EQU 40 ;MAX AUTO COMMAND LENGTH IF NOT BIOSFLG ORG 0 BIOSTBL RB 0 ;BEGINNING OF BIOS TABLES BIOSREL RB 1 ;BIOS RELEASE BIOSREV RB 1 ;BIOS REVISION DEFIOB RB 1 ;DEFAULT I/O BYTE MODE RB 1 ;MODE FLAGS BYTE HECNT RW 1 ;HARD ERROR COUNT (SINCE COLD BOOT) SECNT RW 1 ;SOFT ERROR COUNT (SINCE COLD BOOT) NDISKS RB 1 ;NUMBER OF DISK POSSIBLE IN THIS BIOS ; AUTO EXEC COMMAND BUFFERS AUTOCBC RB AUTOCL+1 ;COLD BOOT AUTO COMMAND AUTOWBC RB AUTOCL+1 ;WARM BOOT AUTO COMMAND ; CHARACTER I/O TABLES CRTTBL RB CIOTBLL ;CRT: (KEYBOARD/DISPLAY) SERATBL RB CIOTBLL ;SERIAL PORT A SERBTBL RB CIOTBLL ;SERIAL PORT B PPRTTBL RB CIOTBLL ;PARALLEL PRINTER PORT DUMMYTBL RB CIOTBLL ;DUMMY UNIT ; DISK PARAMETER ENTRY TABLES DPEBASE RB 0 ;START OF DISK PARAMETER ENTRY TABLES ENDIF IF BIOSFLG BIOSTBL RB 0 ;BEGINNING OF BIOS TABLES BIOSREL DB BREL ;BIOS RELEASE BIOSREV DB BREVSN ;BIOS REVISION DEFIOB DB 00010101B ;DEFAULT I/O BYTE MODE DB 0 ;MODE FLAGS HECNT DW 0 ;HARD ERROR COUNT (SINCE COLD BOOT) SECNT DW 0 ;SOFT ERROR COUNT (SINCE COLD BOOT) NDISKS DB NDRIVES ;NUMBER OF DRIVES POSSIBLE IN THIS BIOS ; AUTO EXEC COMMAND BUFFERS AUTOCBC DB 0 ;COLD BOOT AUTO COMMAND RB AUTOCL AUTOWBC DB 0 ;WARM BOOT AUTO COMMAND RB AUTOCL ; CHARACTER I/O DEVICE TABLES CRTTBL RB 0 ;CRT: TABLE DB 0 DW 0 DB CIOFO,0 DB 0FFH,0 DB 0,0 DB 0,0 DB 0,0,0 DB 0,0,0,0,0,0,0,0 DW 0,0,0,0,0 IF OFFSET $ - OFFSET CRTTBL NE CIOTBLL %: CRT: CIO TABLE IS NOT CORRECT ENDIF SERATBL RB 0 ;TTY: (SERIAL PORT A) DB ZSERA DW EPB480 DB 0,0 DB EPRXR,0 DB EPDCD+EPTXR,0 DB 0,0 DB 0,0,0 DB EPSB1+EPCL8+EPA16X DB 070H DB EPNORM+EPRTS+EPRESE+EPRXEN+EPDTR+EPTXEN DB 0,0,0,0,0 DW 0,0,0,0,0 IF OFFSET $ - OFFSET SERATBL NE CIOTBLL %: TTY: CIO TABLE IS NOT CORRECT ENDIF SERBTBL RB 0 ;UC1: , UR1: , UP1: , UL1: (SERIAL PORT B) DB ZSERB DW EPB300 DB 0,0 DB EPDSR+EPDCD+EPRXR,0 DB EPDSR+EPDCD+EPTXR,0 DB 0,0 DB 0,0,0 DB EPSB1+EPCL8+EPA16X DB 070H DB EPNORM+EPRTS+EPRESE+EPRXEN+EPDTR+EPTXEN DB 0,0,0,0,0 DW 0,0,0,0,0 IF OFFSET $ - OFFSET SERBTBL NE CIOTBLL %: UL1: CIO TABLE IS NOT CORRECT ENDIF PPRTTBL RB 0 ;LPT: (GENERAL DATA PORT PARALLEL PRINTER) DB 0 DW 0 DB 0,0 DB 0,0 DB PPRTBSY,PPRTBSY DB 0,0 DB 0,0,0 DB LPENSE+VSYNCE+PPRTPRM+PPRTSTB DB GDPDDAV DB GDPCAV DB 0 DB GDPBDDV DB GDPCBV DB 0,0 DW 0,0,0,0,0 IF OFFSET $ - OFFSET PPRTTBL NE CIOTBLL %: LPT: CIO TABLE IS NOT CORRECT ENDIF DUMMYTBL RB 0 ;DUMMY UNIT DB 0 DW 0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0,0 DB 0,0,0,0,0,0,0,0 DW 0,0,0,0,0 IF OFFSET $ - OFFSET DUMMYTBL NE CIOTBLL %: DUMMY CIO TABLE IS NOT CORRECT ENDIF DPEBASE RB 0 ENDIF  \ ;** CHARACTER I/O TABLE DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ORG 0 ; TABLE CIOTBL RB 0 CIOBP RB 1 ;BASE PORT CIOBR RW 1 ;BAUD RATE CIOF1 RB 1 ;FLAG BYTE 1 CIOF2 RB 1 ;FLAG BYTE 2 CIOIM RB 1 ;INPUT READY MASK CIOIPM RB 1 ;INPUT READY POLARITY MASK CIOOM RB 1 ;OUTPUT READY MASK CIOOPM RB 1 ;OUTPUT READY POLARITY MASK CIOECNT RB 1 ;# OF CHARACTERS BEFORE SENDING CIOECTR RB 1 ;CHARACTER COUNTER FOR SENDING CIONCHR RB 1 ;SEND NULLS AFTER THIS CHARACTER CIONCNT RB 1 ;# OF NULLS TO SEND CIONCTR RB 1 ;NULL COUNTER CIOVAL1 RB 1 ;DEVICE DEPENDANT VALUE 1 CIOVAL2 RB 1 ;DEVICE DEPENDANT VALUE 2 CIOVAL3 RB 1 ;DEVICE DEPENDANT VALUE 3 CIOVAL4 RB 1 ;DEVICE DEPNEDANT VALUE 4 CIOVAL5 RB 1 ;DEVICE DEPENDANT VALUE 5 CIOVAL6 RB 1 ;DEVICE DEPENDANT VALUE 6 CIOVAL7 RB 1 ;DEVICE DEPENDANT VALUE 7 CIOVAL8 RB 1 ;DEVICE DEPENDANT VALUE 8 CIOIN RW 1 ;ADDRESS OF DEVICE INIT ROUTINE CIOIS RW 1 ;ADDRESS OF INPUT INPUT STATUS ROUTINE CIOID RW 1 ;ADDRESS OF INPUT DATA ROUTINE CIOOS RW 1 ;ADDRESS OF INPUT OUTPUT STATUS ROUTINE CIOOD RW 1 ;ADDRESS OF OUTPUT DATA ROUTINE CIOTBLL EQU OFFSET $-OFFSET CIOTBL ;LENGTH OF CIO TABLE ; FLAG BYTE 1 CIOSPI EQU 0+ 1B ;STRIP PARITY BIT ON INPUT CIOSPO EQU 0- 10B ;STRIP PARITY BIT ON OUTPUT CIOMLI EQU 0 100B ;MAP LOWER CASE ON INPUT CIOMLO EQU 00001000B ;MAP LOWER CASE ON OUTPUT CIOEAH EQU 00010000B ;USE / HANDSHAKING CIODCH EQU 0010- B ;USE / HANDSHAKING CIOFO EQU 010 B ;FAST OUTPUT ; FLAG BYTE 2 CIOW4A EQU CIOEAH ; SENT, WAITING FOR CIOW4D EQU CIODCH ;WAITING FOR q ;** USEFUL CP/M-86 BDOS SYSTEM CONTROL BLOCK DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ORG 0000H SCBDMA RW 1 ;USER DMA ADDRESS OFFSET SCBDMAB RW 1 ;USER DMA ADDRESS BASE SCBCUD RB 1 ;CURRENT USER DISK SCBCUN RB 1 ;CURRENT USER NUMBER ORG 0016H SCBLCP RB 1 ;LISTING TOGGLE -- SET/RESET BY CTL-P SCBCD2S RB 4 ;CURRENT DRIVES TO SEARCH ORG 001BH SCBRDAT RW 1 ;ROLANDER DATE (DAYS SINCE 01/01/78) SCBRTIM RB 0 ;ROLANDER TIME (PACKED BCD) SCBRTH RB 1 ; HOURS SCBRTM RB 1 ; MINUTES SCBRTS RB 1 ; SECONDS SCBADAT RB 0 ;ASCII DATE SCBAMO RB 2 ; MONTH RB 1 ; '/' SCBADY RB 2 ; DAY RB 1 ; '/' SCBAYR RB 2 ; YEAR RB 1 ; END OF STRING SCBATIM RB 0 ;ASCII TIME SCBATH RB 2 ; HOURS RB 1 ; ':' SCBATM RB 2 ; MINUTES RB 1 ; ':' SCBATS RB 2 ; SECONDS RB 1 ; END OF STRING ORG 0040H SCBCONW RB 1 ;CONSOLE WIDTH SCBLSTW RB 1 ;PRINTER WIDTH SCBCONC RB 1 ;CONSOLE COLUMN SCBLSTC RB 1 ;PRINTER COLUMN Q ;** CP/M-86 SYSTEM EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; OS VALUES IN 1ST 1K OF 8088 ADDRESS SPACE BDOSE EQU 224 ;SWI FOR BDOS ENTRY ORG 0DDH*4 LPENHF RB 1 ;LIGHT PEN HIT FLAG (<>0 = HIT) LPENPOS RW 1 ;LIGHT PEN POSITION LPENHIT RB 1 ;LIGTH PEN HIT REGISTER IMAGE ORG 0DEH*4 UTICCNT RW 2 ;USER TIC COUNTER ; RESERVED LOCATIONS IN PAGE ZERO ORG 005CH TFCB RB 36 ;TRANSIENT DEFAULT FCB TFCB2 EQU TFCB+16 ;TRANSIENT 2ND FILENAME ORG 0080H TBUFF RB 128 ;DEFAULT DISK BUFFER ; CP/M FUNCTIONS RESET EQU 0 ;SYSTEM RESET RDCON EQU 1 ;READ CONSOLE WRCON EQU 2 ;WRITE CONSOLE RDRDR EQU 3 ;READ READER WRPUN EQU 4 ;WRITE PUNCH WRLST EQU 5 ;WRITE LIST DCONIO EQU 6 ;DIRECT CONSOLE I/O (2) IOSTAT EQU 7 ;INTERROGATE I/O STATUS ASTAT EQU 8 ;ALTER I/O STATUS PRCONB EQU 9 ;PRINT CONSOLE BUFFER RDCONB EQU 10 ;READ CONSOLE BUFFER CCSTAT EQU 11 ;CHECK CONSOLE STATUS LDH EQU 12 ;LIFT DISK HEAD CPMVER EQU LDH ;GET CP/M VERSION (2) RDS EQU 13 ;RESET DISK SYSTEM SELDSK EQU 14 ;SELECT DISK OPEN EQU 15 ;OPEN FILE CLOSE EQU 16 ;CLOSE FILE S1ST EQU 17 ;SEARCH FIRST SNXT EQU 18 ;SEARCH NEXT DELETE EQU 19 ;DELETE FILE READ EQU 20 ;READ RECORD WRITE EQU 21 ;WRITE RECORD CREATE EQU 22 ;CREATE FILE RENAME EQU 23 ;RENAME FILE ILOG EQU 24 ;INTERROGATE LOGIN IDSK EQU 25 ;INTERROGATE DISK SETDMA EQU 26 ;SET DMA ADDRESS IALLOC EQU 27 ;INTERROGATE ALLOCATION WPD EQU 28 ;WRITE PROTECT DISK GROV EQU 29 ;GET READ/ONLY VECTOR SFA EQU 30 ;SET FILE ATTRIBUTES GADPB EQU 31 ;GET ADDR OF DPB SGUSR EQU 32 ;SET/GET USER CODE READRR EQU 33 ;READ RANDOM RECORD WRITERR EQU 34 ;WRITE RANDOM RECORD CFSIZE EQU 35 ;COMPUTE FILE SIZE SRR EQU 36 ;SET RANDOM RECORD RESDRV EQU 37 ;RESET DRIVE WRITERZ EQU 40 ;WRITE RANDOM WITH ZERO FILL CHAIN EQU 47 ;CHAIN TO ANOTHER PROGRAM GETSCB EQU 49 ;GET ADDR OF BDOS SYSTEM CONTROL BLOCK DBIOS EQU 50 ;DIRECT BIOS CALL SDMASB EQU 51 ;SET DMA SEGMENT BASE GDMASB EQU 52 ;GET DMA SEGMENT BASE GMXAVL EQU 53 ;GET MAXIMUM AVAILABLE MEMORY GABSMX EQU 54 ;GET ABSOLUTE MAXIMUM GMREG EQU 55 ;GET MEMORY REGION GAMREG EQU 56 ;GET ABSOLUTE MEMORY REGION FMREG EQU 57 ;FREE MEMORY REGION FAM EQU 58 ;FREE ALL MEMORY PRGLD EQU 59 ;PROGRAM LOAD ; BIOS ENTRY POINTS. CBOOT EQU 0 ;COLD BOOT WBOOT EQU 1 ;WARM BOOT CONST EQU 2 ;CONSOLE STATUS CONIN EQU 3 ;CONSOLE INPUT CONOUT EQU 4 ;CONSOLE OUTPUT LSTOUT EQU 5 ;LIST OUTPUT PUNOUT EQU 6 ;PUNCH OUTPUT RDRIN EQU 7 ;READER INPUT HOME EQU 8 ;HOME DISK SETDSK EQU 9 ;SET (SELECT) DISK DRIVE SETTRK EQU 10 ;SET TRACK NUMBER SETSEC EQU 11 ;SET SECTOR NUMBER SDMA EQU 12 ;SET DMA ADDRESS BREAD EQU 13 ;READ SELECTED SECTOR BWRITE EQU 14 ;WRITE SELECTED SECTOR BLSTST EQU 15 ;CHECK LIST DEVICE STATUS BSECTRN EQU 16 ;SECTOR TRANSLATE ROUTINE SETDMAB EQU 17 ;SET DMA BASE GETMRT EQU 18 ;GET OFFSET OF MEMORY SEGMENT BASE GETIOB EQU 19 ;GET I/O BYTE SETIOB EQU 20 ;SET I/O BYTE BFMT EQU 21 ;FORMAT BRDTRK EQU 22 ;READ TRACK BWRTRK EQU 23 ;WRITE TRACK BWPC EQU 24 ;WRITE PROTECT CHECK BCBD EQU 25 ;CLEAR BUFFERS FOR DRIVE BGBT EQU 26 ;GET BIOS TABLES BRUN85 EQU 27 ;RUN 8085 PROCESSOR ; BIOS WRITE TYPES BWRNOR EQU 0 ;NORMAL WRITE BWRDIR EQU 1 ;WRITE TO A DIRECTORY SECTOR BRWUA1 EQU 2 ;WRITE TO 1ST SECTOR OF UNALLOC BLOCK ; FILE CONTROL BLOCK ORG 0 FCBDN RB 1 ;DISK NAME FCBFN RB 8 ;FILE NAME FCBFNL EQU 8 ;FILE NAME LENGTH FCBFT RB 3 ;FILE TYPE FCBFTL EQU 3 ;FILE TYPE LENGTH FCBRO EQU FCBFT+0 ;R/O FLAG FCBROF EQU 10B B ; R/O FLAG VALUE FCBSYS EQU FCBFT+1 ;SYS FLAG FCBSYSF EQU 10F B ; SYS FLAG VALUE FCBARC EQU FCBFT+2 ;ARCHIVE FLAG FCBARCF EQU 10\ B ; ARCHIVE FLAG VALUE FCBEX RB 1 ;EXTENT RB 1 FCBRWF RB 1 ;R/W FLAG FCBRWFF EQU 10B ; R/W FLAG VALUE FCBRC RB 1 ;RECORD COUNT FCBDM RB 16 ;DISK ALLOCATION MAP FCBNR RB 1 ;NEXT RECORD TO BE READ OR WRITTEN FCBLS EQU 33 ;FCB LENGTH FOR SEQUENTIAL I/O FCBRR RB 3 ;RANDOM RECORD POINTER FCBLR EQU 36 ;FCB LENGTH FOR RANDOM I/O  f ;** 6821 PERIPHERAL INTERFACE ADAPTER EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; REGISTER DISPLACEMENTS PIADATA EQU 0 ;PERIPHERAL DATA REGISTER A PIADDRA EQU 0 ;DATA DIRECTION REGISTER A PIACTLA EQU 1 ;CONTROL REGISTER A PIADATB EQU 2 ;PERIPHERAL DATA REGISTER B PIADDRB EQU 2 ;DATA DIRECTION REGISTER B PIACTLB EQU 3 ;CONTROL REGISTER B ; CONTROL WORD FORMAT PIAC1 EQU 0M11B ;CONTROL OF CA1(CB1) INTERRUPT LINE PIAC10 EQU 00H ; ACTIVE TRANSITION 1->0 ; IRQ PIN IS DISABLED PIAC11 EQU 01H ; ACTIVE TRANSITION 1->0 ; IRQ PIN IS ENABLED PIAC12 EQU 02H ; ACTIVE TRANSITION 0->1 ; IRQ PIN IS DISABLED PIAC13 EQU 03H ; ACTIVE TRANSITION 0->1 ; IRQ PIN IS ENABLED PIADDAC EQU 0100B ;DATA DIRECTION ACCESS CONTROL BIT ; 0=DATA DIRECTION REG , 1=PERIPHERAL DATA REG PIAC2 EQU 00111000B ;CONTROL OF CA2(CB2) ; INPUT MODES PIAC20 EQU 00H ; ACTIVE TRANSITION 1->0 ; IRQ PIN IS DISABLED PIAC21 EQU 08H ; ACTIVE TRANSITION 1->0 ; IRQ PIN IS ENABLED PIAC22 EQU 10H ; ACTIVE TRANSITION 0->1 ; IRQ PIN IS DISABLED PIAC23 EQU 18H ; ACTIVE TRANSITION 0->1 ; IRQ PIN IS ENABLED ; OUTPUT MODES PIAC24 EQU 20H ; 0 ON R(W) OPERATION , 1 ON ACTIVE CA1(CB1) PIAC25 EQU 28H ; 0 ON R(W) OPERATION , 1 ON E AFTER DESELECT PIAC26 EQU 30H ; RESET PIAC27 EQU 38H ; SET PIAIRQ2 EQU 010# B ;IRQ FOR CA2(CB2) PIAIRQ1 EQU 10 B ;IRQ FOR CA1(CB1) \ ;** 6845 CRT CONTROLLER DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT DISPLACEMENTS CRTREG EQU 0 ;CRT-C REGISTER SELECT CRTDAT EQU 1 ;CRT-C DATA ; CRT-C INTERNAL REGISTERS ; NOTE: A "*" INDICATES THE REGISTER VALUE READ/WRITTEN IS ; ONE LESS THAN ACTUAL VALUE. CRTHT EQU 0 ;* HORIZONTAL TOTAL CRTHD EQU 1 ; HORIZONTAL DISPLAY CRTHSP EQU 2 ;* HORIZONTAL SYNC POSITION CRTSW EQU 3 ; SYNC WIDTH CRTSWWH EQU 00001111B ; HORIZONTAL CRTSWWV EQU 11110000B ; VERTICAL CRTVT EQU 4 ;* VERTICAL TOTAL CRTVTA EQU 5 ; VERTICAL TOTAL ADJUST CRTVD EQU 6 ; VERTICAL DISPLAY CRTVSP EQU 7 ;* VERTICAL SYNC POSITION CRTIS EQU 8 ; INTERLACE AND SKEW CRTISIS EQU 0% 1B ; INTERLACE SYNC CRTISISV EQU 0` 11B ; INTERLACE AND SYNC CRTISDS1 EQU 00010000B ; DISPTMG ONE CHAR SKEW CRTISDS2 EQU 0010U B ; DISPTMG TWO CHAR SKEW CRTISDNO EQU 00110000B ; NON-OUTPUT CRTISCS1 EQU 010+ B ; CURSOR ONE CHAR SKEW CRTISCS2 EQU 10, B ; CURSOR TWO CHAR SKEW CRTISCNO EQU 110v B ; NON-OUTPUT CRTMRA EQU 9 ; MAXIMUM RASTER ADDRESS CRTCSR EQU 10 ; CURSOR START RASTER CRTCSRSRA EQU 0001- B ; START RASTER ADDRESS CRTCSRND EQU 0010& B ; NOT DISPLAYED CRTCSRBS EQU 00102 B ; BLINK SLOW (WITH CRTCSRCB) CRTCSRCB EQU 010%B ; BLINK ENABLE CRTCER EQU 11 ; CURSOR END RASTER CRTSAH EQU 12 ; START ADDRESS (MSB) CRTSAL EQU 13 ; START ADDRESS (LSB) CRTCH EQU 14 ; CURSOR (MSB) CRTCL EQU 15 ; CURSOR (LSB) CRTLPH EQU 16 ; LIGHT PEN ADDRESS (MSB) CRTLPL EQU 17 ; LIGHT PEN ADDRESS (LSB) s ;** DEF8253 - 8253 PROGRAMMABLE INTERVAL TIMER DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT DISPLACEMENTS PITC0 EQU 000H ;COUNTER 0 PITC1 EQU 001H ;COUNTER 1 PITC2 EQU 002H ;COUNTER 2 PITCW EQU 003H ;CONTROL WORD ; CONTROL WORD PITSC EQU 110?B ;SELECT COUNTER PITSC0 EQU 000H ; 0 PITSC1 EQU 040H ; 1 PITSC2 EQU 080H ; 2 PITRL EQU 00110000B ;READ/LOAD PITRLCL EQU 000H ; COUNTER LATCHING OPERATION PITRLMB EQU 010H ; MSB PITRLLB EQU 020H ; LSB PITRLW EQU 030H ; WORD PITM EQU 00001110B ;MODE PITMITC EQU 000H ; 0 - INTERRUPT ON TERMINAL COUNT PITMP1S EQU 002H ; 1 - PROGRAMMABLE ONE SHOT PITMRG EQU 004H ; 2 - RATE GENERATOR PITMSW EQU 006H ; 3 - SQUARE WAVE RATE GENERATOR PITMSTS EQU 008H ; 4 - SOFTWARE TRIGGERED STROBE PITMHTS EQU 00AH ; 5 - HARDWARE TRIGGERED STROBE PITBCD EQU 0? 1B ;0 = 16 BIT BINARY COUNTER ;1 = 4 DIGIT BCD COUNTER J ;** 8259A EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; REGISTER DISPLACEMENTS ICW1 EQU 0 ;ICW1 ICW2 EQU 1 ;ICW2 ICW3 EQU 1 ;ICW3 ICW4 EQU 1 ;ICW4 OCW1 EQU 1 ;OCW1 OCW2 EQU 0 ;OCW2 OCW3 EQU 0 ;OCW3 ; ICW1 REGISTER FLAGS ICW1A EQU 1110u B ;A7-A5 ICW1OP EQU 00010000B ;1=ICW1 , 0=OCW'S ICW1LT EQU 00001000B ;TRIGGER MODE (0=EDGE , 1=LEVEL) ICW1ADI EQU 0- 100B ;CALL INTERVAL (0=8 , 1=4) ICW1SNG EQU 0& 10B ;0=CASCADE , 1=SINGLE ICW1I4 EQU 0V 1B ;ICW4 (0=NOT USED , 1=USED) ; ICW3 REGISTER FLAGS (MASTER DEVICE) ICW3S0 EQU 0% 1B ;IR INPUT 0 HAS SLAVE ICW3S1 EQU 0& 10B ;IR INPUT 1 HAS SLAVE ICW3S2 EQU 0 100B ;IR INPUT 2 HAS SLAVE ICW3S3 EQU 00001000B ;IR INPUT 3 HAS SLAVE ICW3S4 EQU 00010000B ;IR INPUT 4 HAS SLAVE ICW3S5 EQU 0010& B ;IR INPUT 5 HAS SLAVE ICW3S6 EQU 010% B ;IR INPUT 6 HAS SLAVE ICW3S7 EQU 10O B ;IR INPUT 7 HAS SLAVE ; ICW3 REGISTER FLAGS (SLAVE DEVICE) ICW3SID EQU 0 111B ;SLAVE ID MASK ; ICW4 REGISTER FLAGS ICW4SFN EQU 00010000B ;1=SPECIAL FULLY NESTED MODE ICW4BMS EQU 00001000B ;BUFFERED MODE SLAVE ICW4BMM EQU 00001100B ;BUFFERED MODE MASTER ICW4AE EQU 0 10B ;AUTO EOI ICW4UPM EQU 0 1B ;MICRO-PROCESSOR MODE ; (0=8080/85 , 1=8086/88) ; OCW1 REGISTER (INTERRUPT MASK REGISTER) ; 0=ENABLED , 1=DISABLED OCW1IM0 EQU 0 1B ;IR0 OCW1IM1 EQU 0 10B ;IR1 OCW1IM2 EQU 0R 100B ;IR2 OCW1IM3 EQU 00001000B ;IR3 OCW1IM4 EQU 00010000B ;IR4 OCW1IM5 EQU 0010 B ;IR5 OCW1IM6 EQU 010 B ;IR6 OCW1IM7 EQU 10( B ;IR7 ; OCW2 REGISTER OCW2OP EQU 0 B ;OCW2 OCW2R EQU 10# B ;PRIORITY ROTATION OCW2SL EQU 010+ B ;SELECT A SPECIFIC LEVEL OCW2EOI EQU 0010' B ;END OF INTERRUPT COMMAND OCW2L EQU 0` 111B ;IR LEVEL TO BE ACTED UPON ; OCW3 REGISTER OCW3OP EQU 00001000B ;OCW3 OCW3RSM EQU 010+ B ;RESET SPECIAL MASK MODE OCW3SSM EQU 0110$ B ;SET SPECIAL MASK MODE OCW3P EQU 0 100B ;POLL COMMAND OCW3RIR EQU 0 10B ;READ IR REG OCW3RIS EQU 0 11B ;READ IS REG  ;** EP2DEF -- EQUATES FOR ENHANCED PROGRAMMABLE COMMUNICATION ; INTERFACE CHIP 2661-2. ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT DISPLACEMENTS EPDATA EQU 0 ;DATA EPSTAT EQU 1 ;STATUS EPSYN EQU 1 ;SYN1/SYN2/DLE EPMODE EQU 2 ;MODE EPCMD EQU 3 ;COMMAND ; STATUS REGISTER EPTXR EQU 0! 1B ;TRANSMITTER READY EPRXR EQU 0 10B ;RECEIVER READY EPTXE EQU 0# 100B ;TRANSMITTER EMPTY EPDSC EQU 0h 100B ;DATA SET CHANGE EPPE EQU 00001000B ;PARITY ERROR EPOE EQU 00010000B ;OVERRUN ERROR EPFE EQU 0010 B ;FRAME ERROR EPSD EQU 0010 B ;SYNC DETECTED EPDCD EQU 010# B ;DATA CARRIER DETECT EPDSR EQU 105 B ;DATA SET READY ; MODE REGISTER 1 EPMBRF EQU 011B ;MODE AND BAUDRATE FACTOR EPS1X EQU 000H ; SYNCHRONOUS 1X RATE EPA1X EQU 001H ; ASYNCHRONOUS 1X RATE EPA16X EQU 002H ; ASYNCHRONOUS 16X RATE EPA64X EQU 003H ; ASYNCHRONOUS 64X RATE EPCL EQU 00001100B ;CHARACTER LENGTH EPCL5 EQU 000H ; LENGTH 5 EPCL6 EQU 004H ; LENGTH 6 EPCL7 EQU 008H ; LENGTH 7 EPCL8 EQU 00CH ; LENGTH 8 EPPC EQU 00010000B ;PARITY CONTROL (0=DISABLED , 1=ENABLED) EPPT EQU 00100 B ;PARITY TYPE (0=ODD , 1=EVEN) EPASBL EQU 110 B ;ASYNCHRONOUS STOP BIT LENGTH EPSB1 EQU 040H ; LENGTH 1 EPSB15 EQU 080H ; LENGTH 1.5 EPSB2 EQU 0C0H ; LENGTH 2 EPSTC EQU 010R B ;SYNCHRONOUS TRANSPARENCY CONTROL ; (0=NORMAL , 1=TRANSPARENT) EPNSC EQU 10 B ;NUMBER OF SYNC CHARACTERS ; (0=DOUBLE , 1=SINGLE) ; MODE REGISTER 2 EPBRS EQU 00001111B ;BAUD RATE SELECTION EPMR2U EQU 11110000B ;SEE TEXT ; COMMAND REGISTER EPTXEN EQU 0" 1B ;TRANSMITTER ENABLE EPDTR EQU 0& 010B ;DATA TERMINAL READY EPRXEN EQU 0 100B ;RECEIVER ENABLE EPSBRK EQU 00001000B ;SEND BREAK (ASYNC) EPSDLE EQU 00001000B ;SEND DLE (SYNC) EPRESE EQU 00010000B ;RESET STATUS ERRORS EPRTS EQU 0010! B ;REQUEST TO SEND EPOM EQU 110 B ;OPERATING MODE EPNORM EQU 000H ; NORMAL EPOM1 EQU 040H ; MODE 1 EPOMLL EQU 080H ; LOCAL LOOP BACK EPOMRL EQU 0C0H ; REMOTE LOOP BACK ; BAUDRATE SELECTION VALUES EPB455 EQU 0 ;45.5 EPB050 EQU 1 ;50 EPB075 EQU 2 ;75 EPB110 EQU 3 ;110 EPB134 EQU 4 ;134.5 EPB150 EQU 5 ;150 EPB300 EQU 6 ;300 EPB600 EQU 7 ;600 EPB120 EQU 8 ;1200 EPB180 EQU 9 ;1800 EPB200 EQU 10 ;2000 EPB240 EQU 11 ;2400 EPB480 EQU 12 ;4800 EPB960 EQU 13 ;9600 EPB192 EQU 14 ;19200 EPB384 EQU 15 ;38400 U ;** EXTRA OPCODE DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; JMP IMMEDIATE CODEMACRO JMPI A:D DB 0E9H RELW A ENDM ; JMPF IMMEDIATE CODEMACRO JMPFI A:D,B:D DB 0EAH DW A DW B ENDM ; CALL IMMEDIATE CODEMACRO CALLI A:D DB 0E8H RELW A ENDM ; CALLF IMMEDIATE CODEMACRO CALLFI A:D,B:D DB 09AH DW A DW B ENDM ; PUSH ALL REGS (EXCEPT SP,SS,CS) CODEMACRO PUSHA DB 050H ;PUSH AX DB 053H ;PUSH BX DB 051H ;PUSH CX DB 052H ;PUSH DX DB 055H ;PUSH BP DB 056H ;PUSH SI DB 057H ;PUSH DI DB 01EH ;PUSH DS DB 006H ;PUSH ES ENDM ; POP ALL REGS (USED AFTER 'PUSHA') CODEMACRO POPA DB 007H ;POP ES DB 01FH ;POP DS DB 05FH ;POP DI DB 05EH ;POP SI DB 05DH ;POP BP DB 05AH ;POP DX DB 059H ;POP CX DB 05BH ;POP BX DB 058H ;POP AX ENDM  ;** HEATH CP/M DISK LABEL DEFINITIONS ; ; DISK LABELS ARE USED ON MOST DATA DISKS AND ; ON ALL SYSGEN'ED (BOOTABLE) DISKS. ; TO MAINTAIN COMPATIBILITY WITH OLDER RELEASES OF CP/M, ; THE 5 1/4" HARD SECTOR AND 8" SOFT SECTOR FLOPPY DATA DISKS ; DO NOT USE LABELS. ; ; THE LABEL RESIDES ON THE 1ST SECTOR OF TRACK 0, SIDE 0. ; ; AT THE END OF THE LABEL IS A CHECKSUM. ; FOR VERSION # 0 OF THE LABEL, THE CHECKSUM IS CALCULATED ; B BY ADDING UP THE VALUES IN THE LABEL PRIOR TO THE CHECKSUM SLOT ; u A BYTE AT A TIME, THEN TAKING THE ONE'S COMPLEMENT OF THE SUM. ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST LABVER EQU 0 ;CURRENT FORM # FOR LABEL LABBUF EQU 0 ;SLOT FOR JUMP INSTRUCTION AROUND LABEL BDTYPE EQU LABBUF+3 ;SLOT FOR DRIVE TYPE LABEL EQU LABBUF+4 LABTYP EQU LABEL+0 ;SLOT FOR LABEL TYPE LABHTH EQU LABTYP+1 ;SLOT FOR HEATH EXTENSIONS TO DPE LABDPB EQU LABHTH+DPEHL ;SLOT FOR DISK PARAMETER BLOCK LABCS EQU LABDPB+DPBL ;CHECKSUM LABLEN EQU LABCS-LABEL+1 ;LABEL LENGTH  Q ;*** PATCHES TO CCP/BDOS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ZPATCH: MOV CS:ZPATAX,AX ;SAVE REGS MOV CS:ZPATBX,BX MOV CS:ZPATES,ES POP BX ;RETRIEVE IRET INFO & RESTORE POP ES ; INTERRUPT STATUS POPF MOV AL,ES:[BX] ;GET PATCH # MOV CS:ZPATNUM,AL MOV AX,CS:ZPATAX ;RESTORE REGS MOV BX,CS:ZPATBX MOV ES,CS:ZPATES CMP CS:ZPATNUM,2 ;Q. VALID PATCH # JE PATCH02 ; BR IF YES PUSHF ;SET UP AS IF SWI CLI PUSH ES PUSH BX JMP INTX3 ;EXIT THROUGH COMMON SWI EXIT ZPATCHX EQU OFFSET $ DSEG ORG ZPATCHX ZPATNUM RB 1 ZPATAX RW 1 ZPATBX RW 1 ZPATES RW 1 ZPATCHY EQU OFFSET $ CSEG ORG ZPATCHY ;** PATCH #02 ; ; MODIFY CCP TO RUN 8 BIT USER PROGRAM IF 16 BIT ONE IS NOT FOUND. ; PATCH02: IF R8085 LEA DI,COMFCB+9 ;CHANGE FILE TYPE TO '.COM' LEA SI,COMTYPE MOV CX,3 CLD REP MOVSB CALL OPENC ;Q. DOES .COM FILE EXISTS JNZ PATCH02A ; BR IF YES ENDIF CALL RESETDISK JMP JPCOMER IF R8085 ; TRY TO GET 64K BANK OF MEMORY PATCH02A: MOV R85MCBA,1024/16*64 PATCH02B: MOV CL,GAMREG ;ASK FOR 64K OF MEMORY LEA DX,R85MCB ; ALIGNED ON 64K BOUNDARY CALL BDOS CMP AL,0 ;Q. AVAILABLE JE PATCH02D ; BR IF YES ADD R85MCBA,1024/16*64 ;BUMP TO NEXT BANK CMP R85MCBA,1024/16*64*15 ;Q. AT TOP BANK JB PATCH02B ; BR IF NOT -- KEEP TRYING PATCH02C: JMP LOADERR ; LOAD 8085 PROGRAM PATCH02D: CALL LDPROG JC PATCH02C ;BR IF ERROR ; SETUP BASE PAGE OF 8085 RUNTIME PACKAGE INC NCCPALLOC ;INDICATE USER JOB TO BE RUN MOV BX,MEM_STK_PTR ;FLAG 8085 MEMORY SPACE AS USER MOV BYTE PTR 4[BX],1 MOV BX,CS ;CALCULATE CS V ALUE ADD BX,(OFFSET R85)/16 MOV R85CS,BX ;PLACE INTO BASE PAGE JMP GOUSER PATCH02X EQU OFFSET $ DSEG ORG PATCH02X COMTYPE DB 'COM' ENDIF PATCH02Y EQU OFFSET $ CSEG ORG 046CH  ;! RESETDISK:  ;! ORG 072FH ;! JPCOMER:  ;! IF R8085 ORG 008BH ;! BDOS:  ;! ORG 00EDH ;! OPENC:  ;! ORG 06DCH ;! LOADERR:  ;! ORG 0738H ;! GOUSER:  ;! DSEG ORG 0827H  ;! COMFCB RB 0  ;! ORG 2393H  ;! NCCPALLOC RB 1  ;! MEM_STK_PTR RW 1 & ;! CSEG ORG PATCH02Y ENDIF  ;** R85PKG ; ; RUN TIME PACKAGE FOR RUNNING 8085 PROCESSOR UNDER CP/M-86 ; ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; V"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; DEFINE PAGE 0 R85X EQU (OFFSET $+15)/16*16 DSEG ORG R85X R85 DW R85L DB 0 R85CS RW 1 DB 1 RB 256-(OFFSET $ - OFFSET R85) R85X1 EQU OFFSET $ CSEG ORG R85X1 JMPF DWORD PTR (R85ACS-OFFSET R85) ;ADJUST (CS),(IP) R851: MOV AX,CS ;ADJUST (DS) MOV DS,AX MOV SS,AX ;SET UP MY OWN STACK LEA SP,TFCB ; MOVE 8085 CODE TO TOP OF BANK TO BE USED BY 8085 MOV CX,STUB1L MOV SI,OFFSET STUB1 LEA DI,BDOS85 MOV ES,R85MCBA CLD REP MOVSB MOV CX,STUB2L MOV SI,OFFSET STUB2 LEA DI,BIOS85 REP MOVSB MOV CX,STUB3L MOV SI,OFFSET STUB3 LEA DI,COMTCOD REP MOVSB ; SETUP 8085 BANK PAGE 0 MOV CL,IOSTAT ;I/O BYTE INT BDOSE MOV ES,R85MCBA MOV ES:.3,AL MOV ES: BYTE PTR .0,0C3H ;8085 START UP ADDRESS LEA AX,BIOS85 ; LATER CHANGED BY STUB MOV ES:.1,AX ; TO WARM BOOT MOV ES: BYTE PTR .5,0C3H ;ENTRY FOR BDOS LEA AX,BDOS85E MOV ES:.6,AX MOV CX,0100H-005CH ;MOVE DEFAULT FCB'S & COMMAND STRING LEA SI,R85+OFFSET TFCB LEA DI,TFCB CLD REP MOVSB ; SETUP AS IF ENTERING FROM CCP MOV CL,SETDMA ;DEFAULT DMA AT 0080H MOV DX,0080H INT BDOSE MOV CL,SDMASB MOV DX,R85MCBA ; IN 8085 MEMORY BANK INT BDOSE EJECT ;** EXECUTE CYCLE FOR 8085 RUN TIME PACKAGE ; MOV ES,R85MCBA MOV ES:COMWHO,ZPSPPS8 MOV ES:COMFLG,0 MOV CL,12 MOV AX,ES SHR AX,CL OUT ZHAL,AL MOV R85MEM,ES SWAP85: MOV ES,R85MCBA MOV ES:COMWHO,ZPSPPS5+ZPSPI88 SWAP851: MOV AL,ZPSPPS5+ZPSPI88 OUT ZPSP,AL JMPS SWAP852 SWAP852: MOV ES ,R85MCBA ;BACK FROM 8085 -- DETERMINE WHAT TO DO TEST ES:COMFLG,COMBDOS ;Q. REQ FOR BDOS FUNCTION JZ SWAP853 ; BR IF NOT CALL BDOSH JMPS SWAP85 SWAP853: TEST ES:COMFLG,COMBIOS ;Q. REQ FOR BIOS FUNCTION JZ SWAP85 ; BR IF NOT CALL BIOSH JMPS SWAP85 ;* BDOS HANDLER ; BDOSH: MOV ES,R85MCBA ;GET FUNCTION # MOV CL,ES: BYTE PTR COMVAL1 CMP CL,WRITERZ ;Q. LEGAL FUNCTION JE BDOSH0 ; BR IF YES CMP CL,RESDRV JBE BDOSH0 ; BR IF YES MOV ES:COMVAL1,0FFFFH ; ELSE RETURN HEX FF'S AS VALUE MOV ES:COMVAL2,0FFFFH RET BDOSH0: CMP CL,RESET ;Q. SYSTEM RESET JNE BDOSH0A ; BR IF NOT MOV ES,R85MCBA ;SETUP FOR SYSTEM RESET MOV ES:COMVAL2,0 ; FREEING MEMORY JMPS BDOSH1 BDOSH0A: CMP CL,ASTAT ;Q. ALTER I/O BYTE JNE BDOSH1 ; BR IF NOT MOV AL,ES: BYTE PTR COMVAL2 MOV ES:.3,AL ;PLACE NEW IMAGE IN 8085 PAGE ZERO BDOSH1: PUSH CX ;REMEMBER FUNCTION # PUSH DS ;PERFORM CP/M-86 BDOS CALL MOV DS,R85MCBA MOV DX,COMVAL2 INT BDOSE MOV COMVAL1,AX ;PLACE RETURN VALUES IN COM REGION MOV COMVAL2,BX POP DS POP CX ;RETRIEVE FUNCTION # CMP CL,IOSTAT ;Q. GET I/O BYTE JNE BDOSH3 ; BR IF NOT MOV ES,R85MCBA ;UPDATE 8085 PAGE 0 BYTE MOV ES:.3,AL JMPS BDOSH8 BDOSH3: CMP CL,IALLOC ;Q. GET ADDRESS ALLOCATION VECTOR JNE BDOSH4 ; BR IF NOT PUSH DS MOV CX,ALV85L MOV SI,BX LEA DI,ALV85 MOV DS,R85MCBA MOV COMVAL2,DI CALL EXDSES CLD REP MOVSB POP DS JMPS BDOSH8 BDOSH4: CMP CL,GADPB ;Q. GET ADDRESS OF DPB JNE BDOSH8 ; BR IF NOT PUSH DS MOV CX,DPBL MOV SI,BX LEA DI,DPB85 MOV DS,R85MCBA MOV COMVAL2,DI CALL EXDSES CLD REP MOVSB POP DS BDOSH8: RET ;* BIOS HANDLER ; BIOSH: MOV ES,R85MCBA ;GET FUNCTION # MOV AL,ES:COMFUNC MOV R85BF,AL ;SAVE FUNCTION # CMP AL,WBOOT ;Q. COLD OR WARM BOOT JA BIOSH1 ; BR IF NOT MOV ES:COMVAL1,RESET ;HANDLE AS BDOS FUNCTION 0 JMP BDOSH BIOSH1: MOV CX,ES:COMVAL1 MOV DX,ES:COMVAL2 MOV AH,AL ADD AL,AL ADD AL,AH MOV AH,0 ADD AX,OFFSET BIOSJMP CALL AX MOV ES,R85MCBA ;PLACE RETURN VALUES IN COM REGION MOV ES:COMVAL1,AX MOV ES:COMVAL2,BX CMP R85BF,SETDSK ;Q. SET DISK JNE BIOSH9 ; BR IF NOT CMP BX,0 ;Q. ERROR JE BIOSH9 ; BR IF YES MOV ES,R85MCBA MOV CX,DPEL ;MOVE AND ADJUST ADDRESS OF DPE MOV SI,BX LEA DI,DPE85 MOV ES:COMVAL2,DI CLD REP MOVSB MOV CX,DPBL ;MOVE AND ADJUST ADDRESS OF DPB MOV SI,DPEDPB[BX] LEA DI,DPB85 MOV ES: WORD PTR DPE85+OFFSET DPEDPB,DI CLD REP MOVSB MOV CX,ALV85L ;MOVE AND ADJUST ADDRESS OF ALV MOV SI,DPEALV[BX] LEA DI,ALV85 MOV ES: WORD PTR DPE85+OFFSET DPEALV,DI CLD REP MOVSB BIOSH9: RET ;* LOAD 8080 PROGRAM ; LDPROG: PUSH ES MOV CL,SETDMA ;SETUP BUFFER FOR LOADING LEA DX,R85+OFFSET TBUFF INT BDOSE MOV CL,SDMASB MOV DX,CS INT BDOSE ; LOOP AND LOAD PROGRAM LDPROG1: MOV COMFCB+OFFSET FCBNR,0 ;INIT FILE POINTER MOV R85LPTR,0100H ;INIT LOAD POINTER LDPROG2: MOV CL,READ ;READ NEXT RECORD LEA DX,COMFCB INT BDOSE CMP AL,0 JNE LDPROG7 ; BR IF ERROR -- ASSUME EOF MOV DI,R85LPTR ;GET LOAD POINTER ADD DI,128 ;Q. WILL BUFFER FIT IN 8080 MEMORY CMP DI,OFFSET BDOS85 ; BELOW BDOS JAE LDPROG8 ; BR IF NOT XCHG DI,R85LPTR ;SAVE UPDATED LOAD POINTER MOV CX,128/2 ;MOVE RECORD TO 8080 MEMORY LEA SI,R85+OFFSET TBUFF MOV ES,R85MCBA CLD REP MOVSW JMPS LDPROG2 ;LOOP AND READ LDPROG7: CLC ;INDICATE NO ERROR JMPS LDPROG9 LDPROG8: STC ;INDICATE ERROR LDPROG9: PUSHF MOV CL,CLOSE ;CLOSE FILE LEA DX,COMFCB INT BDOSE POPF POP ES RET R85X2 EQU OFFSET $ DSEG ORG R85X2 ;* 8085 BDOS, BIOS, TERMINATE STUBS ;#85 STUB1 DB 02EH,000H,000H,000H,000H,001H,03EH,002H DB 032H,0F4H,0FFH,079H,032H,0F7H,0FFH,0EBH DB 022H,0F9H,0FFH,0F3H,03EH,000H,0D3H,0FEH DB 03EH,080H,032H,0F5H,0FFH,0D3H,0FEH,03AH DB 0F4H,0FFH,0E6H,001H,0C2H,0FBH,0FFH,03AH DB 0F7H,0FFH,047H,02AH,0F9H,0FFH,0C9H STUB1L EQU OFFSET $ - OFFSET STUB1 STUB2 DB 0C3H,033H,0FEH,0C3H,049H,0FEH,0C3H,04EH DB 0FEH,0C3H,053H,0FEH,0C3H,058H,0FEH,0C3H DB 05DH,0FEH,0C3H,062H,0FEH,0C3H,067H,0FEH DB 0C3H,06CH,0FEH,0C3H,071H,0FEH,0C3H,076H DB 0FEH,0C3H,07BH,0FEH,0C3H,080H,0FEH,0C3H DB 085H,0FEH,0C3H,08AH,0FEH,0C3H,08FH,0FEH DB 0C3H,094H,0FEH,021H,003H,0FEH,022H,001H DB 000H,021H,049H,0FEH,022H,001H,0FEH,031H DB 0C2H,0FEH,021H,000H,000H,0E5H,0C3H,000H DB 001H,00EH,000H,0C3H,006H,0FDH,03EH,002H DB 0C3H,096H,0FEH,03EH,003H,0C3H,096H,0FEH DB 03EH,004H,0C3H,096H,0FEH,03EH,005H,0C3H DB 096H,0FEH,03EH,006H,0C3H,096H,0FEH,03EH DB 007H,0C3H,096H,0FEH,03EH,008H,0C3H,096H DB 0FEH,03EH,009H,0C3H,096H,0FEH,03EH,00AH DB 0C3H,096H,0FEH,03EH,00BH,0C3H,096H,0FEH DB 03EH,00CH,0C3H,096H,0FEH,03EH,00DH,0C3H DB 096H,0FEH,03EH,00EH,0C3H,096H,0FEH,03EH DB 00FH,0C3H,096H,0FEH,03EH,010H,032H,0F6H DB 0FFH,03EH,004H,032H,0F4H,0FFH,060H,069H DB 022H,0F7H,0FFH,0EBH,022H,0F9H,0FFH,0C3H DB 013H,0FDH STUB2L EQU OFFSET $ - OFFSET STUB2 STUB3 DB 0F3H,03EH,080H,0D3H,0FEH STUB3L EQU OFFSET $ - OFFSET STUB3 ;#85 ;* VARIABLES USED IN RUNNING 8085 PROCESSOR R85MEM RW 1 ;PARAGRAPH VALUE OF 64K BANK OF MEMORY `; USED BY 8085 R85ACS DW OFFSET R851 ;JMPF VALUE FOR ADJUSTING (CS),(IP) R85BCS RW 1 IF (OFFSET R85ACS) LT (OFFSET R85) %: 'R85ACS' MUST BE AFTER 'R85' ENDIF R85MCB RB 0 ;MEMORY CONTROL BLOCK R85MCBA RW 1 DW 1024/16*64 RB 1 R85LPTR RW 1 ;PROGRAM LOAD POINTER R85BF RB 1 ;BIOS FUNCTION # R85L EQU OFFSET $ - OFFSET R85 q ;** DEFINITIONS FOR RUNNING 8085 PROCESSOR UNDER CP/M-86 ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;* STUB AREA DEFINITIONS ALV85L EQU 256 ORG 0FD00H BDOS85 RB 6 BDOS85E RB 0FE00H-0FD00H-DPEL-DPBL-6 DPE85 RB DPEL DPB85 RB DPBL ORG 0FE00H BIOS85 RB 0FFF4H-0FE00H-ALV85L ALV85 RB ALV85L ;* COMMUNICATION REGION ; THIS AREA IS PLACED AT THE TOP OF THE 64K BANK ; ASSIGNED TO THE 8085 ORG 0FFF4H COMREG RB 0 COMFLG RB 1 ;FLAGS COMWHO RB 1 ;WHO IS TO GET CONTROL (COPY OF ; VALUE IN PROCESSOR SWAP PORT) COMFUNC RB 1 ;BIOS FUNCTION COMVAL1 RW 1 ;VALUE 1 COMVAL2 RW 1 ;VALUE 2 COMTCOD RW 0 ;START OF 8085 TERMINATION CODE ; FLAG BYTE BIT DEFINITIONS COMTERM EQU 0! 1B ;TERMINATE 8085 COMBDOS EQU 0) 10B ;BDOS FUNCTION REQUEST COMBIOS EQU 0 100B ;BIOS FUNCTION REQUEST  [ ;** SOFTWARE BOOT CODE DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST SBCSBC EQU 0 ;LOGICAL SECTOR # OF SBC ORG 0 SBCJMP RB 3 ;JUMP TO SOFTWARE BOOT CODE SBCVER RB 1 ;SOFTWARE BOOT CODE VERSION NUMBER SBCREV RB 1 ;SOFTWARE BOOT CODE REVISION NUMBER SBCDBS RB 27 ;DEFAULT BOOT STRING SBCBSA RB 3 ;SECTOR ADDR OF BAD SECTOR TABLE A SBCBSB RB 3 ;SECTOR ADDR OF BAD SECTOR TABLE B SBCSBA RB 3 ;SECTOR ADDR OF SUPER BLOCK A SBCSBB RB 3 ;SECTOR ADDR OF SUPER BLOCK B SBCSSZ RW 1 ;SECTOR SIZE SBCSPT RW 1 ;SECTORS PER TRACK SBCTPC RW 1 ;TRACKS PER CYLINDER SBCCPV RW 1 ;CYLINDERS PER VOLUME SBCSPS RW 1 ;SECTORS PER REGION SBCVSZ RB 3 ;VOLUME SIZE (SECTORS PER VOLUME) SBCNSL RB 1 ;NUMBER OF REGIONS - 1 SBCCSA RW 1 ;CHECKSUM: SUPER BLOCK A SBCCSB RW 1 ;CHECKSUM: SUPER BLOCK B SBCCBA RW 1 ;CHECKSUM: BAD SECTOR TABLE A SBCCBB RW 1 ;CHECKSUM: BAD SECTOR TABLE B SBCSDP RB 12 ;SET DRIVE PARAMETERS SBCFUS RB 3 ;FIRST USER SECTOR NUMBER SBCDATE RB 6 ;DATE PARTITIONED SBCCRC RW 1 ;CRC OF SBC (ASSUMIN SBCCRC=0) RB 39 ;RESERVED SBCLEN EQU 0080H ;SBC LENGTH ; SUPER BLOCK DEFINITIONS SPBNE EQU 16 ;NUMBER OF ENTRIES ORG 0 SPBPNL EQU 16 ;MAXIMUM LENGTH OF PARTITION NAME SPBPN RB SPBPNL ;PARTITION NAME SPBOSL EQU 10 ;MAXIMUM LENGTH OF OS NAME SPBOS RB SPBOSL ;OS NAME SPBFLG RB 1 ;FLAG BYTE SPBFSN RB 3 ;FIRST SECTOR # OF PARTITION ; (LOW,MID,HIGH) SPBPEL EQU 30 ;LENGTH OF ENTRY ; SUPER BLOCK FLAG BYTE SPBFPNF EQU 10W B ;PARTITION NOT FORMATTED ; BAD SECTOR TABLE SBCBEL EQU 3 ;LENGTH OF ENTRY ;*** TIMER DRIVER ; ; * * * N O T E * * * ; IN ORDER FOR THE 8253 TO HAVE TIME TO PROCESS INFO BETWEEN MULTIPLE ; OUTPUTS AND OUTPUT/INPUTS, A DUMMY INPUT FROM THE DIP SWITCH PORT IS ; DONE TO PROVIDE THE NECESSARY DELAY. ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;** INITIALIZATION ; INTIM: PUSHF CLI ; MAKE SURE ALL COUNTER READ CYCLES ARE COMPLETED IN AL,ZTIMER+PITC0 IN AL,ZDIPSW IN AL,ZTIMER+PITC0 IN AL,ZDIPSW IN AL,ZTIMER+PITC1 IN AL,ZDIPSW IN AL,ZTIMER+PITC1 IN AL,ZDIPSW IN AL,ZTIMER+PITC2 IN AL,ZDIPSW IN AL,ZTIMER+PITC2 ; INIT COUNTER MODES IN AL,ZDIPSW MOV AL,PITSC0+PITRLW+PITMSW OUT ZTIMER+PITCW,AL ;COUNTER 0 - SQUARE WAVE GENERATOR IN AL,ZDIPSW MOV AL,PITSC1+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;COUNTER 1 - EVENT COUNTER IN AL,ZDIPSW MOV AL,PITSC2+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;COUNTER 2 - INT ON TERMINAL COUNT ; INIT COUNTER VALUES IN AL,ZDIPSW MOV AL,0 ;TIMER 1 OUT ZTIMER+PITC1,AL IN AL,ZDIPSW MOV AL,0 OUT ZTIMER+PITC1,AL IN AL,ZDIPSW MOV AX,TIMEVAL ;TIMER 0 OUT ZTIMER+PITC0,AL IN AL,ZDIPSW MOV AL,AH OUT ZTIMER+PITC0,AL ; WAIT FOR FIRST RISING CLOCK FROM COUNTER 0 MOV AL,NOT TIMERS0 OUT ZTSTAT,AL XOR CX,CX INTIM1: IN AL,ZTSTAT TEST AL,TIMERS0 LOOPZ INTIM1 JCXZ TIMERR ; CLEAR ANY PENDING INTERRUPTS MOV AL,NOT (TIMERS0+TIMERS2) OUT ZTSTAT,AL ; INIT WORK VARIABLES MOV TIMEFLG,0 MOV PTICCNT,0 MOV TICCNT,0 MOV TICCNT+2,0 MOV TODHSEC,0 MOV CL,GETSCB ;GET ADDRESS OF CP/M-86 SCB INT BDOSE MOV CPMSCB,BX MOV CX,TODINTL ;INIT SCB DATE & TIME FIELDS LEA SI,TODINT LEA DI,SCBRDAT[BX] m CLD REP MOVSB POPF RET ;* TIMER NOT RUNNING TIMERR: LEA SI,TIMERRM CALL PMSG JMP SYSHLT ;** TIMER INTERRUPT HANDLER ; INTTIM: POP CS:ISAVPC ;SET UP INTERRUPT LOCAL STACK CALL ISETSTK PUSHA ;SAVE ALL REGS MOV AX,CS ;GET DS VALUE MOV DS,AX ; CHECK CAUSE OF INTERRUPT IN AL,ZTSTAT ;GET CAUSE OF TIMER INTERRUPT TEST AL,TIMERS0 ;Q. IS IT TIMER 0 JNZ TIM0INT ; BR IF YES TEST AL,TIMERS2 ;Q. IS IT TIMER 2 ; JNZ TIM2INT ; BR IF YES JZ $+5 JMP TIM2INT ;* TIMER INTERRUPT HANDLER EXIT TIMINTX: POPA JMP INTX2 ;* HANDLE TIMER 0 INTERRUPTS TIM0INT: MOV AL,PITSC1+PITRLCL OUT ZTIMER+PITCW,AL ;LATCH COUNTER 1 VALUE IN AL,ZDIPSW IN AL,ZTIMER+PITC1 ;GET COUNTER 1 VALUE MOV AH,AL IN AL,ZDIPSW IN AL,ZTIMER+PITC1 XCHG AH,AL XCHG PTICCNT,AX ;(AX)=PREVIOUS COUNTER VALUE ;'PTICCNT'=CURRENT COUNTER VALUE SUB AX,PTICCNT ;(AX)=# TIC'S ADD TICCNT,AX ;ADD # TIC'S TO 32 BIT TIC COUNTER ADC TICCNT+2,0 MOV BX,0 ;ADD # TIC'S TO USER TIC COUNTER MOV ES,BX ADD ES:UTICCNT,AX ADC ES:UTICCNT+2,0 IF R8085 CMP R85MEM,0 ;Q. 8085 PROCESSOR RUNNING JE TIM0INT1 ; BR IF NOT MOV ES,R85MEM ;UPDATE 8 BIT'S TICCNT ADD ES: WORD PTR .000BH,AX ADC ES: WORD PTR .000DH,0 ENDIF TIM0INT1: ; HANDLE FUNCTIONS ASSOCIATED WITH Z207 CMP Z207HUD,0 ;Q. HEAD UNLOAD DELAY DONE JE TIM0INT2 ; BR IF YES SUB Z207HUD,AX ; UPDATE VALUE JAE TIM0INT2 MOV Z207HUD,0 TIM0INT2: CMP Z207DSEL,0 ;Q. TIME TO DESELECT DRIVE JE TIM0INT3 ; BR IF NOT SUB Z207DSEL,AX ; UPDATE VALUE JA TIM0INT3 ; BR IF STILL NOT TIME TO DESELECT PUSH AX ; DESELECT DRIVE MOV AL,0 OUT FDCON,AL MOV DEVCTL,AL POP AX MOV Z207DSEL,0 ;INSURE SLOT CONTAINS 0 MOV Z207HUD,Z207HUDV ;SET HEAD UNLOAD DELAY ; TIM0INT3: CALL TOD ;UPDATE TOD MOV AL,NOT TIMERS0 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMP TIMINTX ;* HANDLE TIMER 2 INTERRUPTS TIM2INT: MOV TIMEFLG,1 ;SET FLAG MOV AL,NOT TIMERS2 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMP TIMINTX ;** TOD - TIME OF DAY HANDLER (UPDATES CP/M-86 SYSTEM CONTROL ; BLOCK DATE AND TIME FIELDS) TOD: MOV DI,CPMSCB ;GET OFFSET OF SCB ADD AX,TODHSEC ;COMPUTE NEW HUNDREDTHS CMP AX,200 ;Q. DID A LOT OF TIME GO BY (2 SEC) JB TOD1 ; BR IF NOT ; PRELIMINARY HANDLING IF >= 2 SEC BETWEEN TIMER INTERRUPTS XOR DX,DX ;COMPUTE MINUTES/SECONDS/HUNDREDTHS MOV CX,100 DIV CX MOV TODHSEC,DX ;UPDATE HUNDREDTHS MOV CL,60 DIV CL MOV CX,AX ; (CH)=SECONDS , (CL)=MINUTES JMPS TOD2 ; UPDATE HUNDREDTHS TOD1: MOV TODHSEC,AX ;UPDATE HUNDREDTHS MOV CX,0100H ;INCREMENT VALUES FOR SECONDS/MINUTES SUB AX,100 ;Q. MORE THAN 1 SEC ; JC TOD9 ; BR IF NOT JNC $+5 JMP TOD9 MOV TODHSEC,AX ;UPDATE HUNDREDTHS ; UPDATE SECONDS TOD2: MOV AX,WORD PTR SCBATS[DI] ;GET ASCII SECONDS FROM SCB XCHG AL,AH AND AX,0F0FH AAD ;CONVERT TO BINARY ADD AL,CH ;ADD IN SECONDS SINCE LAST UPDATE MOV DL,AL ;Q. >= 60 SECONDS SUB DL,60 JC TOD3 ; BR IF NOT MOV AL,DL ;UPDATE SECONDS INC CL ;UPDATE MINUTES INCREMENT TOD3: AAM ;CONVERT TO ASCII XCHG AL,AH OR AX,'00' MOV WORD PTR SCBATS[DI],AX ;SAVE IN SCB AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTS[DI],AL ; UPDATE MINUTES CMP CL,0 ;Q. UPDATE MINUTES ; JE TOD9 ; BR IF NOT JNE $+5 JMP TOD9 MOV AX,WORD PTR SCBATM[DI] ;GET ASCII MINUTES FROM SCB XCHG AL,AH AND AX,0F0FH AAD ;CONVERT TO BINARY ADD AL,CL ;ADD IN MINUTES SINCE LAST UPDATE MOV DL,AL ;Q. >= 60 MINUTES SUB DL,60 JC TOD4 ; BR IF NOT MOV AL,DL ;UPDATE MINUTES TOD4: RCR DL,1 ;SAVE CARRY FLAG AAM ;CONVERT TO ASCII XCHG AL,AH OR AX,'00' MOV WORD PTR SCBATM[DI],AX ;SAVE IN SCB AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTM[DI],AL ; UPDATE HOURS RCL DL,1 ;RESTORE CARRY ; JC TOD9 ;BR IF NOT TIME TO UPDATE HOURS JNC $+5 JMP TOD9 MOV AX,WORD PTR SCBATH[DI] ;GET HOURS FROM SCB XCHG AL,AH ADD AL,1 ;BUMP BY 1 AAA OR AL,'0' CMP AX,'24' ;Q. >= 24 HOURS JB TOD5 ; BR IF NOT MOV AX,'00' ;UPDATE HOURS TOD5: RCR DL,1 ;SAVE CARRY FLAG XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBATH[DI],AX AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTH[DI],AL ; UPDATE DAYS RCL DL,1 ;RESTORE CARRY JB TOD9 ;BR IF NOT TIME TO UPDATE DAYS INC SCBRDAT[DI] ;BUMP ROLANDER DATE FIELD MOV AX,WORD PTR SCBAMO[DI] ;DETERMINE # DAYS IN MONTH XCHG AL,AH AND AX,0F0FH AAD MOV BX,AX DEC BX SHL BX,1 MOV DX,TODDAYS[BX] CMP AL,2 ;Q. FEBRUARY JNE TOD6 ; BR IF NOT TEST SCBAYR+1[DI],03H ;Q. LEAP YEAR JNZ TOD6 ; BR IF NOT MOV DX,'29' ;29 DAYS IN MONTH TOD6: MOV AX,WORD PTR SCBADY[DI] ;GET DAYS FROM SCB XCHG AL,AH CMP AX,DX ;Q. ALREADY LAST DAY OF MONTH JB TOD7 ; BR IF NOT MOV AX,'00' ; RESET DAYS TOD7: RCR DL,1 ;SAVE CARRY FLAG ADD AL,1 ;BUMP DAYS AAA OR AL,'0' XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBADY[DI],AX ; UPDATE MONTH RCL DL,1 ;RESTORE CARRY FLAG JB TOD9 ;BR IF NOT TIME TO UPDATE MONTHS MOV AX,WORD PTR SCBAMO[DI] ;GET MONTHS FROM SCB XCHG AL,AH ADD AL,1 ;BUMP 1 MONTH AAA OR AL,'0' CMP AX,'13' ;Q. >= 13 MONTHS JB TOD8 ; BR IF NOT MOV AX,'01' ;RESET MONTHS TOD8: XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBAMO[DI],AX ; UPDATE YEARS JB TOD9 ;BR IF NOT TIME TO UPDATE YEARS MOV DX,WORD PTR SCBAYR[DI] ;GET YEARS FROM SCB MOV AL,1 ;BUMP 1 YEAR ADD AL,DH AAA MOV DH,AL MOV AL,0 ADC AL,DL AAA MOV AH,DH OR AX,'00' MOV WORD PTR SCBAYR[DI],AX ;SAVE IN SCB ; TOD9: RET ;** DELAY ROUTINES USING TIMER 2 ; ; MAXIMUM DELAY IS 65536*4 uS (~262 mS) ; ; COUNTER VALUE FOR N mS = N*250 ; COUNTER VALUE FOR N uS = (N+3)/4 ;* WDLY - SET TIMER AND WAIT ; ; ENTRY: (AX)=COUNTER VALUE ; EXIT: NONE ; USES: NONE ; WDLY: CALL NWDLY ;SET TIMER WDLY1: CMP TIMEFLG,0 ;Q. TIME UP JE WDLY1 ; BR IF NOT RET ;* NWDLY - SET TIMER RUNNING AND DO NOT WAIT ; ; ENTRY: (AX)=COUNTER VALUE ; EXIT: NONE ; USES: NONE ; NWDLY: PUSH AX PUSH AX MOV AL,PITSC2+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;SET MODE (ALSO STOPS TIMER 2) IN AL,ZDIPSW POP AX PUSHF ;DISABLE INTERRUPTS CLI MOV TIMEFLG,0 ;CLEAR TIMER 2 FLAG OUT ZTIMER+PITC2,AL ;INSERT TIMER COUNTER VALUE IN AL,ZDIPSW MOV AL,AH OUT ZTIMER+PITC2,AL POPF ;RESTORE INTERRUPT STATUS POP AX RET  X ;** Z-MACHINE TIMER DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; p"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; TIMER STATUS FLAGS TIMERS0 EQU 0$ 1B ;TIMER 0 INTERRUPT TIMERS2 EQU 0 10B ;TIMER 2 INTERRUPT ; TIMER VALUES TIMEVAL EQU 2500 ;10 mS DIVIDE BY N VALUE TINTRVL EQU 10 ;TIMER 1 INTERVAL (IN mS)  I ;** Z207 EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT ASSIGNMENTS FDBASE EQU 0B0H ;BASE PORT ADDRESS FDCMD EQU FDBASE ;1797 COMMAND REGISTER FDSTA EQU FDBASE ; % STATUS REGISTER FDTRK EQU FDBASE+1 ; $ TRACK REGISTER FDSEC EQU FDBASE+2 ; % SECTOR REGISTER FDDAT EQU FDBASE+3 ; ,DATA REGISTER FDCON EQU FDBASE+4 ;DISK CONTROL PORT FDAS EQU FDBASE+5 ;AUX STATUS PORT ; COMMANDS FDCRST EQU 000H ;RESTORE FDCSEK EQU 010H ;SEEK FDCSTP EQU 020H ;STEP FDCSTI EQU 040H ;STEP IN FDCSTO EQU 060H ;STEP OUT FDCRDS EQU 080H ;READ SECTOR FDCWRS EQU 0A0H ;WRITE SECTOR FDCRDA EQU 0C0H ;READ ADDRESS FDCRDT EQU 0E0H ;READ TRACK FDCWRT EQU 0F0H ;WRITE TRACK FDCFI EQU 0D0H ;FORCE INTERRUPT ; TYPE 1 COMMAND FLAGS FDFUTR EQU 00010000B ;UPDATE TRACK REGISTER FDFHLB EQU 00001000B ;HEAD LOAD AT BEGINNING FDFVRF EQU 0E 100B ;VERIFY FLAGS ; TYPE 1 COMMAND STEP RATE FLAGS FDFSRM EQU 0 11B ;STEP RATE MASK FDFS6 EQU 0" B ;STEP RATE 6(3) MS FDFS12 EQU 0 1B ;  12(6) FDFS20 EQU 0 10B ;  20(10) FDFS30 EQU 0 11B ; 30(15) ; TYPE 2&3 COMMAND FLAGS FDFMRF EQU 00010000B ;MULTIPLE RECORD FLAG FDFSLF EQU 00001000B ;SECTOR LENGTH FLAG FDFDLF EQU 0 100B ;30 MS DELAY FDFSS1 EQU 0 10B ;SELECT SIDE 1 FDFDDM EQU 0> 1B ;DELETED DATA MARK ; TYPE 4 COMMAND FLAGS FDFINI EQU 0+ B ;TERMINATE WITH NO INTERRUPT FDFII0 EQU 0. 1B ;NOT READY TO READY TRANSITION FDFII1 EQU 0/ 10B ;READY TO NOT READY TRANSITION FDFII2 EQU 0^ 100B ;INDEX PULSE FDFII3 EQU 00001000B ;IMMEDIATE INTERRUPT ; STATUS FLAGS FDSNRD EQU 10 B ;NOT RE ADY FDSWPV EQU 010* B ;WRITE PROTECT VIOLATION FDSHLD EQU 0010! B ;HEAD IS LOADED FDSRTE EQU 0010 B ;RECORD TYPE FDSWTF EQU 0010 B ;WRITE FAULT FDSSEK EQU 00010000B ;SEEK ERROR FDSRNF EQU 00010000B ;RECORD NOT FOUND FDSCRC EQU 00001000B ;CRC ERROR FDSTK0 EQU 0 100B ;FOUND TRACK 0 FDSLDT EQU 0 100B ;LOST DATA FDSIND EQU 0 10B ;INDEX HOLE FDSDRQ EQU 0 10B ;DRQ FDSBSY EQU 01B ;BUSY ; INFO RETURNED BY A READ ADDRESS COMMAND FDRATRK EQU 0 ;TRACK FDRASID EQU 1 ;SIDE FDRASEC EQU 2 ;SECTOR FDRASL EQU 3 ;SECTOR LENGTH FDRACRC EQU 4 ;2 BYTE CRC FDRAL EQU 6 ;LENGTH OF READ ADDRESS INFO ; DISK HEADER SECTOR LENGTH VALUES FDSL128 EQU 0 ;SECTOR LENGTH 128 FDSL256 EQU 1 ;SECTOR LENGTH 256 FDSL512 EQU 2 ;SECTOR LENGTH 512 FDSL1K EQU 3 ;SECTOR LENGTH 1024 ; CONTROL REGISTER FLAGS CONDS EQU 0# 11B ;DRIVE SELECT BITS CONDS8 EQU 0 100B ;0=5 1/4" , 1=8" CONDSEN EQU 00001000B ;DRIVE SELECT ENABLE CONPC EQU 00010000B ;WRITE PRE-COMPENSATION ; 5 1/4" 0=YES , 1=NO ; 8" 0=ALL TRACKS , 1=TRACKS 44-76 CON5FS EQU 0010! B ;5 1/4" FAST STEP CONWE EQU 010* B ;ENABLE WAIT FOR DRQ OR IRQ CONSD EQU 10J B ;ENABLE SINGLE DENSITY ; AUXILARY STATUS REGISTER FLAGS ASIRQ EQU 0% 1B ;1797 INTERRUPT REQUEST ASMO EQU 0 10B ;5 1/4" MOTOR ON AS96T EQU 00001000B ;5 1/4" DRIVES ARE 96TPI AS5PC EQU 00010000B ;5 1/4" DRIVES NEED WRITE PRE-COMPENSATION AS2S EQU 0108 B ;SELECTED 8" DRIVE CONTAINS 2 SIDED MEDIA ASDRQ EQU 10B ;1797 DRQ ; MISCELLANEOUS VALUES NTRKS37 EQU 40 ;# TRACKS SINGLE DENSITY 5 1/4" (48 TPI) NTRKD37 EQU 80 ;# TRACKS DOUBLE DENSITY 5 1/4" (96 TPI) NTRK837 EQU 77 ;NUMBER OF TRACKS 8" NSBT37 EQU 52 ;NUMBER OF CP/M RECORDS TO BE LOADED AT BOOT  P ;*** Z207 DEVICE DRIVER ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST WAIT EQU TRUE ;USE WAIT STATE I/O Z207MRC EQU 12 ;MAX # RETRIES Z207HUDV EQU 35/TINTRVL+1 ;HEAD UNLOAD DELAY (~35mS) Z207DSELV EQU 2000/TINTRVL ;DESELECT VALUE (~2000mS) ;** DRIVER ENTRY JUMP VECTORS ; DRVR207: JMP SEL207 ;SELECT JMP RDT207 ;READ TRACK JMP WRT207 ;WRITE TRACK JMP MNT207 ;MOUNT JMP FMT207 ;FORMAT JMP WPC207 ;WRITE PROTECT CHECK ;** INITIALIZE DRIVE TABLES ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; IN207: ;* RESTORE THE HEAD ON EACH DRIVE TO DETERMINE IF IT EXISTS MOV CX,4 ;# OF Z207 DRIVES LEA BP,DPEBASE ;START ADDRESS OF Z207 DPE'S OR DSKOP,DSKOPI ;INDICATE INIT IN PROGRESS IN2071: PUSH CX CALL DS207 ;SELECT DRIVE CALL RST207 ;RESTORE HEAD TEST AL,FDSTK0 ;Q. TRACK 0 INDICATION JNZ IN2073 ; BR IF YES OR DPEFLG2[BP],DPEIMG ;FLAG DRIVE AS IMAGINARY IN2073: TEST DPEUNIT[BP],CONDS8 ;Q. 8" DRIVE JNZ IN2074 ; BR IF YES IN AL,FDAS ;DETERMINE IF 5 1/4" DRIVE IS TEST AL,AS96T ; 48 OR 96 TPI AND INDICATE THIS JZ IN2074 ; IN TABLE OR DPEFLAG[BP],DPE96T IN2074: ADD BP,DPEL ;BUMP TO NEXT DRIVE TABLE POP CX LOOP IN2071 ;LOOP AND CHECK ALL DRIVES AND DSKOP,NOT DSKOPI ;INDICATE INIT DONE CALL DONE207 ;TURN OFF DRIVES ;* DO DRIVE MAPPING & REAL/IMAGINARY TABLE INITIALIZATION XOR AX,AX MOV ES,AX MOV ES,ES: .MTRDSEG ;GET ADDRESS OF MONITOR DATA AREA MOV CL,ES: MTRBU ;GET BOOT DEVICE UNIT # MOV AL,ES: MTRBI ;GET BOOT DEVICE INDEX # CMP AL,1 ;Q. BOOT DEVICE WAS 8" DRIVE JE IN2076 ; BR IF YES ; BOOT DEVICE WAS 5 1/4" DRIVE; BUILD 5 1/4" TABLES THEN 8" TABLES MOV CH,2 ;# DRIVE TABLES MOV DH,0 ;START OF 5 1/4" TABLES CALL CBTFIL ;FILL IN TABLES MOV CL,0 ;UNIT # MOV CH,2 ;# DRIVE TABLES MOV DH,2 ;START OF 8" TABLES CALL CBTFIL ;FILL IN TABLES RET ; BOOT DEVICE WAS 8" DRIVE; BUILD 8" TABLES THEN 5 1/4" TABLES IN2076: MOV CH,2 ;# DRIVE TABLES MOV DH,2 ;START OF 8" TABLES CALL CBTFIL ;FILL IN TABLES MOV CL,0 ;UNIT # MOV CH,2 ;# DRIVE TABLES MOV DH,0 ;START OF 5 1/4" TABLES CALL CBTFIL ;FILL IN TABLES RET ;** SELECT DRIVE FOR 1ST LOGIN ; ; ENTRY: 'PHYDPE'=ADDRESS OF DPE FOR DRIVE ; (BX)=POINTER TO BUFFER HEADER INFO ; 'XLATES'=ADDRESS OF XLATE TABLE ADDRESSES ; EXIT: 'PHYDPE'=STATUS ; 0=ERROR , OTHERWISE SAME AS ON ENTRY ; USES: AX,CX,BP,SI,DI ; SEL207: OR DSKOP,DSKOPS ;INDICATE SELECT OPERATION IN PROGRESS MOV BP,BUFDPE[BX] MOV DPETRK[BP],DPEUNK ;INDICATE DRIVE HEAD POSITION UNKNOWN TEST DPEUNIT[BP],CONDS8 ;Q. 8" DRIVE JZ $+5 JMP SEL2075 ; BR IF 8" DRIVE ;* SELECT ROUTINE FOR 5 1/4" DRIVES ; READ LABEL MOV PHYTRK,0 ;LABEL IS ON TRACK 0 MOV PHYSID,0 ; SIDE 0 MOV PHYSEC,0 ; 1ST SECTOR CALL RDY2070 ;READY CHECK CMP BUFERR[BX],0 ;Q. DRIVE NOT READY ; JE SEL2079 ; BR IF NOT READY JNE $+5 JMP SEL2079 MOV BUFERR[BX],0 ;CLEAR ERROR FLAG CALL DS207 ;SELECT DRIVE CALL RST207 ;RESTORE HEAD MOV COUNT,1024 ;MAXIMUM SECTOR LENGTH LES DI,DWORD PTR BUFBUF[BX] ;USE HOST BUFFER CALL RDS207 ;TRY READING LABEL AT DENSITY TEST AL,AL ; CURRENTLY INDICATED IN TABLES JZ SEL2072 ; BR IF ABLE TO READ LABEL SECTOR XOR DEVCTL,CONSD ;UNABLE TO READ LABEL SECTOR MOV AL,DEVCTL ; CHANGE TO OTHER DENSITY OUT FDCON,AL LES DI,DWORD PTR BUFBUF[BX] ;TRY TO READ LABEL SECTOR AGAIN CALL RDS207 TEST AL,AL ; JNZ SEL2079 ; BR IF ERROR JZ $+5 JMP SEL2079 SEL2072: LES SI,DWORD PTR BUFBUF[BX] ;CHECK CHECKSUM OF LABEL ADD SI,LABEL CALL CHKLAB JZ SEL2072A ; BR IF NO ERROR TEST DPEFLAG[BP],DPEDD ;Q. DOUBLE DENSITY DISK ; JZ SEL2079 ; BR IF NOT JNZ $+5 JMP SEL2079 MOV CX,LABCS-LABEL ;ASSUME NOT ZDS CP/M DISK BUT SET UP LEA SI,DL207 ; DEFAULT LABEL AS IF IBM PC CP/M DISK LES DI,DWORD PTR BUFBUF[BX] ; DOUBLE DENSITY/SINGLE SIDED/48 TPI LEA DI,LABEL[DI] CLD REP MOVSB ; MOVE LABEL INFO TO DPE'S HEATH EXTENSIONS SEL2072A: LES SI,DWORD PTR BUFBUF[BX] AND DPEFLAG[BP],DPETYPE+DPE96T MOV AL,ES: LABHTH+(OFFSET DPEFLAG)-(OFFSET DPEHTH) [SI] AND AL,DPEDD+DPE2S OR DPEFLAG[BP],AL ;FLAG BYTE #1 MOV AL,ES: LABHTH+(OFFSET DPERPS)-(OFFSET DPEHTH) [SI] MOV DPERPS[BP],AL ;CP/M RECORDS PER PHYSICAL SECTOR MOV AL,ES: LABHTH+(OFFSET DPERPAB)-(OFFSET DPEHTH) [SI] MOV DPERPAB[BP],AL ;CP/M RECORDS PER ALLOCATION BLOCK AND DPEFLG2[BP],NOT DPE96TM MOV AL,ES: LABHTH+(OFFSET DPEFLG2)-(OFFSET DPEHTH) [SI] AND AL,DPE96TM OR DPEFLG2[BP],AL ;FLAG BYTE #2 ; IF LABEL INDICATES THAT THE MEDIA IS DOUBLE SIDED, THEN ; CHECK OUT THE DRIVE FOR DOUBLE SIDED CAPABILITY TEST DPEFLAG[BP],DPE2S ;Q. DOUBLE SIDED MEDIA JZ SEL2073 ; BR IF NOT MOV PHYSID,FDFSS1 ;TRY TO READ A SECTOR HEADER LEA DI,RDABUF ; ON 2ND SIDE CALL RDA207 TEST AL,AL ; JNZ SEL2079 ; BR IF ERROR JZ $+5 JMP SEL2079 CMP RDABUF+FDRASID,1 ;CHECK SIDE INFO ; JNE SEL2079 ; BR IF NOT 2ND SIDE JE $+5 JMP SEL2079 ; STEP IN 2 TRACKS, READ ADDRESS, AND STEP BACK OUT 2 TRACKS. ; IF READ ADDRESS FINDS TRACK 1 INSTEAD OF TRACK 2, ; THEN ASSUME 48 TPI MEDIA GENERATED ; ON A 48 TPI DRIVE WAS INSERTED INTO THE 96 TPI DRIVE; THEREFOR, ; USE AS A R/O DISK WITH DOUBLE STEPPING. ; ; THERE ARE TWO 48 TPI MEDIA FORMATS THAT ARE SUPPORTED ON ; A 96 TPI DRIVE. ; 1) MEDIA WAS FORMATTED ON A 96 TPI DRIVE AND ONLY USES ; = THE FIRST HALF OF THE DISK SURFACE. (E.G. A 48 TPI MEDIA ; l IS DUPLICATED ONTO MEDIA IN A 96 TPI DRIVE) ; 2) MEDIA WAS FORMATTED ON A 48 TPI DRIVE. THE HARDWARE ; 2 GROUP HAS INFORMED ME THAT THE 96 TPI DRIVE CAN RE LIABLY ; : READ SUCH MEDIA BUT CANNOT WRITE ON IT. TO GO BETWEEN ; TRACKS IT IS NECESSARY TO DOUBLE THE NUMBER OF STEPS. ; ; THE FOLLOWING ARE THE POSSIBLE OUTCOMES OF THE READ ADDRESS ; MEDIA  DRIVE  DRIVE OUTCOME ;  FORMAT  GENERATED ON INSERTED IN  TRACK ; - - - - ; 48 TPI  48 TPI  48 TPI 2 ; 48 TPI  48 TPI  96 TPI  1 ;  48 TPI  96 TPI  48 TPI  ERROR ;  48 TPI  96 TPI  96 TPI  2 ;  96 TPI  96 TPI  48 TPI  ERROR ;  96 TPI  96 TPI  96 TPI 2 ; SEL2073: MOV PHYTRK,2 ;STEP IN TWO TRACKS CALL SDT207 MOV PHYSID,0 ;DO READ ADDRESS LEA DI,RDABUF CALL RDA207 TEST AL,AL ; JNZ SEL2079 ; BR IF ERROR JZ $+5 JMP SEL2079 CMP RDABUF+FDRATRK,2 ;CHECK IF TRACK 2 JE SEL2073A ; BR IF YES ( ; 1) 48 TPI MEDIA GENERATED ON 48 TPI  ; " DRIVE INSERTED INTO 48 TPI DRIVE ( ; 2) 48 TPI MEDIA GENERATED ON 96 TPI  ; " DRIVE INSERTED INTO 96 TPI DRIVE ; 3) 96 TPI MEDIA INSERTED IN 96 TPI CMP RDABUF+FDRATRK,1 ;CHECK IF TRACK 1 ; JNE SEL2079 ; BR IF NOT (ERROR) JE $+5 JMP SEL2079 OR DPEFLAG[BP],DPE48RO ;SET FLAG TO INDICATE 48 TPI MEDIA & ; GENERATED ON 48 TPI DRIVE INSERTED ! ; INTO 96 TPI DRIVE. THE MEDIA X ; IS TREATED AS R/O SEL2073A: CALL RST207 ;STEP OUT TWO TRACKS BY DOING RESTORE ; MOVE LABEL INFO TO DISK PARAMETER BLOCK LES SI,DWORD PTR BUFBUF[BX] ADD SI,LABDPB MOV DI,DPEDPB[BP] MOV CX,DPBL CLD CALL EXDSES REP MOVSB CALL EXDSES JMP SEL2078 ;* SELECT FOR 8" DRIVE SEL2075: MOV PHYTRK,2 ;ATTEMPT TO READ ADDRESS HEADER MOV PHYSID,0 ; ON PHYSICAL TRACK #2 SIDE 0 CALL DS207 ; AT THE CURRENT DENSITY IN CALL RST207 ; THE DRIVE'S DPE CALL SDT207 LEA DI,RDABUF CALL RDA207 TEST AL,AL JZ SEL2075A ;BR IF ABLE TO READ XOR DPEFLAG[BP],DPEDD ;CHANGE TO OTHER DENSITY XOR DEVCTL,CONSD MOV AL,DEVCTL OUT FDCON,AL LEA DI,RDABUF ;ATTEMPT TO READ ADDRESS HEADER CALL RDA207 ; AT OTHER DENSITY TEST AL,AL JNZ SEL2079 ;BR IF ERROR SEL2075A: AND DPEFLAG[BP],NOT DPET0SD ;ASSUME TRACK 0 IS SAME DENSITY TEST DPEFLAG[BP],DPEDD ;Q. DISK IS DOUBLE DENSITY JZ SEL2076 ; BR IF NOT MOV PHYTRK,0 ;CHECK IF TRACK 0 IS SINGLE DENSITY CALL SDT207 ; BY TRYING TO READ ADDRESS HEADER LEA DI,RDABUF2 ; AT DOUBLE DENSITY CALL RDA207 TEST AL,AL ;Q. ERROR JZ SEL2076 ; BR IF NOT -- TRACK 0 IS ALSO DOUBLE OR DPEFLAG[BP],DPET0SD ; OTHERWISE ASSUME TRACK 0 IS SINGLE ; UPDATE REST OF DPE SEL2076: AND DPEFLAG[BP],NOT DPE2S ;# OF SIDES IN AL,FDAS ;ASK DRIVE HOW MANY SIDES TEST AL,AS2S JZ SEL2076A OR DPEFLAG[BP],DPE2S SEL2076A: MOV SI,DPEDD+DPE2S ;COMPUTE ADDRESS OF TABLE CONTAINING AND SI,WORD PTR DPEFLAG[BP] ; INFO FOR UPDATE IF (DPEDD NE 2) OR (DPE2S NE 1) %: DPEDD MUST BE 2 AND DPE2S MUST BE 1 ENDIF SHL SI,1 SHL SI,1 XOR AH,AH MOV AL,RDABUF+FDRASL ADD SI,AX SHL SI,1 MOV SI,TBL207[SI] ;GET ADDRESS OF UPDATE INFO TEST SI,SI ;CHECK FOR NOT SUPPORTED FORMAT JZ SEL2079 ; BR IF NOT SUPPORTED CLD LODSW ;XLATE TABLE ADDRESS MOV DPEXLT[BP],AX LODSB ;CP/M RECORDS PER PHYSICAL SECTOR MOV DPERPS[BP],AL LODSB ;CP/M RECORDS PER ALLOCATION BLOCK MOV DPERPAB[BP],AL MOV DI,DPEDPB[BP] ;DPB MOV CX,DPBL CLD MOV AX,DS MOV ES,AX REP MOVSB ;* DONE WITH SELECT OPERATION SEL2078: AND DSKOP,NOT DSKOPS ;INDICATE DONE WITH SELECT OPERATION JMP DONE207 ;RETURN VIA 'DONE207' ;* ERROR OCCURRED SEL2079: MOV PHYDPE,0 ;INDICATE ERROR JMPS SEL2078 ;** READ TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=NO ERROR , 1=ERROR ; USES: AX,DI ; RDT207: CALL SET207 ;SETUP CALL SDT207 ;SEEK DESIRED TRACK CALL S1S207 ;SET 1ST SECTOR TO READ LES DI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS > ADD DI,AX RDT2071: CMP PREREAD,0 ;Q. DOING PREREAD JNE RDT2072 ; BR IF YES CMP BUFERR[BX],0 ;Q. ABORT JNE RDT2073 ; BR IF YES RDT2072: CALL RDS207 ;READ NEXT SECTOR RDT2073: ADD DI,COUNT ;BUMP BUFFER POINTER INC PHYSEC ;BUMP PHYSICAL SECTOR # MOV AL,BYTE PTR PHYSEC ;CHECK IF SECTOR # WRAPAROUND CMP AL,SECCNT JB RDT2074 ; BR IF NOT XOR AX,AX ; OTHERWISE START AT BEGINNING MOV PHYSEC,AX MOV DI,BUFBUF[BX] RDT2074: CMP AL,SEC1ST ;CHECK IF ALL OF TRACK READ JNE RDT2071 ; BR IF NOT JMP DONE207 ;RETURN THRU 'DONE207' ;** WRITE TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=NO ERROR , 1=ERROR ; USES: AX,SI,DI ; WRT207: CALL SET207 ;SETUP CALL SDT207 ;SEEK DESIRED TRACK CALL S1S207 ;SET 1ST SECTOR TO WRITE LES SI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS ADD SI,AX WRT2071: MOV DI,BUFSECF[BX] ;CHECK IF PHYSICAL SECTOR IS DIRTY ADD DI,PHYSEC TEST BYTE PTR [DI],1 JZ WRT2073 ; BR IF IT IS NOT MOV BYTE PTR [DI],0 ;CLEAR DIRTY SECTOR FLAG CMP BUFERR[BX],0 ;Q. ABORT JNE WRT2073 ; BR IF YES -- SKIP PHYSICAL WRITE CALL WRS207 ;WRITE SECTOR WRT2073: ADD SI,COUNT ;SKIP BUFFER POINTER TO NEXT SECTOR INC PHYSEC ;BUMP PHYSICAL SECTOR # MOV AL,BYTE PTR PHYSEC ;CHECK IF SECTOR # WRAPAROUND CMP AL,SECCNT JB WRT2074 ; BR IF NOT XOR AX,AX ; OTHERWISE SET TO START MOV PHYSEC,AX MOV SI,BUFBUF[BX] WRT2074: CMP AL,SEC1ST ;CHECK IF ALL OF TRACK WRITTEN JNE WRT2071 ; BR IF NOT CALL WBS207 ;WAIT FOR WRITE GATE TURN OFF JMP DONE207 ;RETURN THRU 'DONE207' ;** MOUNT ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: NONE ; USES: DI ; MNT207: MOV DI,BUFDPE[BX] ;SET TRACK POSITION TO UNKNOWN MOV DPETRK[DI],DPEUNK RET ;** FORMAT TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; 'FVFLG'=VERIFY FLAG ; 'DMAPTR'=ADDRESS OF TRACK IMAGE (OFFSET) ; 'DMASEG'=ADDRESS OF TRACK IMAGE (SEGMENT) ; EXIT: 'ERROR'=ERROR STATUS ; USES: AX,CX,DX,SI ; FMT207: CALL SET207 ;SETUP CALL SDT207 ;SEEK DESIRED TRACK OR DSKOP,DSKOPF ;INDICATE FORMAT OPERATION IN PROGRESS CALL SRC207 ;SET RETRY COUNTER TEST DPEUNIT[BP],CONDS8 ;Q. TIME FOR SPECIAL CHECK JZ FMT2071 ; IF 8" DRIVE CMP PHYTRK,0 ; 0 TRACK 0 JNE FMT2071 ; CMP PHYSID,FDFSS1 ;  SIDE 1 JNE FMT2071 ; hBR IF NOT IN AL,FDAS ;Q. IS DOUBLE SIDED DISKETTE INSERTED TEST AL,AS2S JNZ FMT2071 ; BR IF YES MOV AL,FDSNRD ; ELSE -- FLAGS AS NOT READY ERROR JMPS FMT2072 FMT2071: MOV AL,PHYSID ;GET SIDE SELECT FLAG OR AL,FDCWRT ; OR IN COMMAND OR AL,HLDDLYF ; OR IN DELAY FLAG MOV HLDDLYF,0 ;ZERO DELAY FLAG FOR NEXT I/O LES SI,DWORD PTR DMAPTR ;GET ADDRESS OF TRACK IMAGE MOV CX,12000 ;USE LARGE COUNT CALL WR207 ;USE LOW LEVEL WRITE ROUTINE TEST AL,AL ;Q. ERROR JZ FMT2073 ; BR IF NOT CALL WBS207 ;WAIT BEFORE STEPPING FMT2072: CALL ERR207 ;Q. SHOULD I RETRY JNC FMT2071 ; BR IF YES AND DSKOP,NOT DSKOPF ; OTHERWISE EXIT JMP FMT2074 FMT2073: AND DSKOP,NOT DSKOPF ;INDICATE FORMAT OPERATION OVER CMP FVFLG,0 ;Q. SHOULD I VERIFY JZ FMT2074 ; BR IF NOT MOV PREREAD,0 CALL RDT207 ;TRY READING TRACK FMT2074: JMP DONE207 ;** WRITE PROTECT CHECK ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=R/W , 1=R/O ; USES: AL,BP ; WPC207: MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE OR DSKOP,DSKOPWP ;INDICATE WRITE PROTECT OPERATION CALL DS207 ;SELECT DRIVE MOV AL,FDCFI+FDFINI ;FORCE TYPE 1 STATUS OUT FDCMD,AL PUSH AX MOV AX,(60+3)/4 CALL WDLY POP AX WPC2071: IN AL,FDSTA ;WAIT FOR CONTROLLER NOT BUSY TEST AL,FDSBSY JNZ WPC2071 AND AL,FDSWPV ;ISOLATE WRITE PROTECT BIT MOV AL,0 ;ASSUME R/W JZ WPC2072 ; BR IF R/W MOV AL,1 ;INDICATE R/O WPC2072: MOV BUFERR[BX],AL ;RETURN VALUE AND DSKOP,NOT DSKOPWP ;INDICATE WRITE PROTECT OP DONE JMP DONE207 ;RET VIA 'DONE2 07' ;** READY CHECK ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER ; EXIT: 'BUFERR[BX]'=STATUS (0=NOT READY , 1=READY) ; USES: AL,DX,BP ; RDY207: MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE CALL RDY2070 JMP DONE207 RDY2070: MOV BUFERR[BX],0 ;ASSUME NOT READY OR DSKOP,DSKOPRD ;INDICATE READY CHECK IN PROGRESS CALL DS207 ;SELECT DRIVE MOV DX,5000/TINTRVL+1 ;COMPUTE TIMEOUT COUNT (5 SEC) ADD DX,TICCNT MOV AL,FDCFI+FDFII2 ;WAIT FOR INDEX HOLE TRANSITION OUT FDCMD,AL PUSH AX MOV AX,(60+3)/4 CALL WDLY POP AX RDY2071: CMP DX,TICCNT ;Q. TIMEOUT JE RDY2073 ; BR IF YES IN AL,FDAS ;Q. INDEX HOLE FOUND TEST AL,ASIRQ JZ RDY2071 ; BR IF NOT RDY2072: IN AL,FDSTA ;WAIT FOR 1797 TO GO NOT BUSY TEST AL,FDSBSY JNZ RDY2072 MOV BUFERR[BX],1 ;INDICATE DRIVE READY RDY2073: AND DSKOP,NOT DSKOPRD ;INDICATE READY CHECK DONE RET ;* READ SECTOR ; ; ENTRY: 'PHYSEC'=SECTOR # ; (DI),(ES)=BUFFER POINTER ; EXIT: (AL)=CONTROLLER STATUS ; USES: AL,CX ; RDS207: OR DSKOP,DSKOPR ;INDICATE READ OPERATION IN PROGRESS CALL SRC207 ;SET RETRY COUNTER MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV AL,BYTE PTR PHYSEC ;GET SECTOR # INC AL ;PUT INTO RANGE 1 TO SPT OUT FDSEC,AL ;TELL CONTROLLER RDS2071: MOV AL,PHYSID ;GET SIDE SELECT VALUE OR AL,FDCRDS+FDFSLF ;FORM COMMAND OR AL,HLDDLYF ; OR IN DELAY FLAG MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O MOV CX,COUNT ;GET COUNT LES DI,DWORD PTR HSTPTR ;GET BUFFER POINTER CALL RD207 ;USE LOW LEVEL READ ROUTINE AND AL,NOT FDSRTE ;MASK ERROR CODE TEST AL,AL ;CHECK FOR ERROR JZ RDS2073 ; BR IF NO ERROR CALL ERR207 ;CHECK IF I SHOULD DO RETRY JNC RDS2071 ; BR IF YES CMP PREREAD,0 ;Q. IS THIS A PREREAD OPERATION JNE RDS2074 ; BR IF YES CALL ABTIGN ;HANDLE ABORT/IGNORE RDS2074: MOV AL,ERRTYP ;RESTORE ERROR CODE RDS2073: LES DI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPR ;INDICATE READ OPERATION DONE RET ;* LOW LEVEL READ ROUTINE ; ; ENTRY: (AL)=COMMAND ; (DI),(ES)=BUFFER POINTER ; (CX)=COUNT ; EXIT: (AL)=CONTROLLER STATUS ; USES: AX,CX,DI ; RD207: MOV AH,AL ;SAVE COMMAND IN AL,FDDAT ;CLEAR ANY PENDING DRQ IF WAIT MOV AL,DEVCTL ;ENABLE WAIT STATE I/O OR AL,CONWE OUT FDCON,AL ENDIF CLD ;FORWARD DIRECTION PUSHF ;DISABLE INTERRUPTS CLI MOV AL,AH ;RESTORE COMMAND OUT FDCMD,AL ;ISSUE COMMAND RD2071: IF NOT WAIT IN AL,FDAS ;WAIT FOR DRQ OR IRQ TEST AL,ASDRQ+ASIRQ JZ RD2071 ENDIF IN AL,FDDAT ;GET DATA STOSB ;STORE IN BUFFER LOOP RD2071 ;LOOP AND READ POPF ;RESTORE INTERRUPT STATUS CALL WAIT2071 ;WAIT FOR COMMAND COMPLETION IF WAIT MOV AH,AL ;SAVE CONTROLLER STATUS MOV AL,DEVCTL ;DISABLE WAIT STATE I/O OUT FDCON,AL MOV AL,AH ;RESTORE CONTROLLER STATUS ENDIF RET ;* RDA207 - READ ADDRESS ; ; ENTRY: (DI)=BUFFER ADDRESS OFFSET ; EXIT: (AL)=CONTROLLER STATUS ; USES: AL,CX,DI ; RDA207: OR DSKOP,DSKOPRA ;SHOW READ ADDR OP IN PROGRESS MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,DS RDA2071: MOV AL,PHYSID ;GET SIDE FLAG VALUE OR AL,FDCRDA ; OR IN COMMAND OR AL,HLDDLYF ; OR IN DELAY FLAG MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O MOV CX,FDRAL ;COUNT LES DI,DWORD PTR HSTPTR ;GET BUFFER POINTER CALL RD207 ;USE LOW LEVEL READ ROUTINE AND DSKOP,NOT DSKOPRA ;INDICATE READ ADDRESS OP DONE RET ;* S1S - SET 1ST SECTOR ; ; ENTRY: NONE ; EXIT: (AX)=BUFFER DISPLACEMENT ; 'PHYSEC','SEC1ST'=1ST SECTOR # ; USES: AX,DI ; S1S207: LEA DI,RDABUF ;USE READ ADDRESS BUFFER CALL RDA207 ; TO DO READ ADDRESS OPERATION LEA DI,RDABUF ;GET ADDR OF READ ADDRESS INFO TEST AL,AL ;CHECK IF READ ADDRESS RETURN ERROR JZ S1S2071 ; BR IF NO ERROR MOV BYTE PTR FDRASEC[DI],0 ; OTHERWISE 0 S1S2071: MOV AL,FDRASEC[DI] ;GET SECTOR # CMP AL,SECCNT ;CHECK IF LAST SECTOR ON TRACK JB S1S2072 ; BR IF NOT XOR AL,AL ; OTHERWISE 0 S1 S2072: MOV SEC1ST,AL ;SAVE AS 1ST SECTOR # CBW ;SET 'PHYSEC' MOV PHYSEC,AX MUL COUNT ;COMPUTE DISPLACEMENT RET ;* WRS207 - WRITE SECTOR ; ; ENTRY: 'PHYSEC'=SECTOR # ; (SI),(ES)=BUFFER POINTER ; EXIT: (AL)=CONTROLLER STATUS ; USES: AL,CX,DX ; WRS207: OR DSKOP,DSKOPW ;INDICATE WRITE OPERATION IN PROGRESS CALL SRC207 ;SET RETRY COUNTER MOV HSTPTR,SI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV AL,BYTE PTR PHYSEC ;GET SECTOR # INC AL ;PUT INTO RANGE 1 TO SPT OUT FDSEC,AL ;TELL CONTROLLER WRS2071: MOV AL,PHYSID ;GET SIDE SELECT VALUE OR AL,FDCWRS+FDFSLF ;FORM COMMAND OR AL,HLDDLYF ; OR IN DELAY FLAG MOV HLDDLYF,0 ;ZERO DELAY FOR NEXT I/O MOV CX,COUNT ;GET COUNT LES SI,DWORD PTR HSTPTR ;GET BUFFER POINTER CALL WR207 ;USE LOW LEVEL WRITE ROUTINE TEST AL,AL ;CHECK FOR ERROR JZ WRS2073 ; BR IF NO ERROR CALL WBS207 ;WAIT FOR WRITE GATE TURN OFF CALL ERR207 ;CHECK IF I SHOULD DO RETRY JNC WRS2071 ; BR IF YES CALL ABTIGN ;ASK ABOUT ABORTING MOV AL,ERRTYP ;RESTORE ERROR CODE WRS2073: LES SI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPW ;INDICATE WRITE OP DONE RET ;* WR207 - LOW LEVEL WRITE ROUTINE ; ; ENTRY: (AL)=COMMAND ; (SI)=BUFFER POINTER (OFFSET) ; (ES)=BUFFER POINTER (SEGMENT) ; (CX)=COUNT ; EXIT: (AL)=CONTROLLER STATUS ; USES: AX,CX,SI ; WR207: MOV AH,AL ;SAVE COMMAND MOV AL,FDSWPV ;ASSUME WRITE PROTECT VIOLATION TEST DPEFLAG[BP],DPE48RO ;CHECK FOR 48 TPI R/O DISK JNZ WR2072 ; BR IF IT IS IN AL,FDDAT ;CLEAR ANY PENDING DRQ IF WAIT MOV AL,DEVCTL ;ENABLE WAIT STATE I/O OR AL,CONWE OUT FDCON,AL ENDIF PUSHF ;DISABLE INTERRUPTS CLI CLD ;FORWARD DIRECTION CALL EXDSES ;GET DATA SEGMENT MOV AL,AH OUT FDCMD,AL ;ISSUE COMMAND WR2071: IF NOT WAIT IN AL,FDAS ;WAIT FOR DRQ OR IRQ TEST AL,ASDRQ+ASIRQ JZ WR2071 ENDIF LODSB ;GET DATA OUT FDDAT,AL ;SEND TO DISK LOOP WR2071 ;LOAD AND WRITE CALL EXDSES ;RESTORE DATA SEGMENT POPF ;RESTORE INTERRUPT STATUS CALL WAIT2071 ;WAIT FOR COMMAND COMPLETION IF WAIT MOV AH,AL ;SAVE CONTROLLER STATUS MOV AL,DEVCTL ;DISABLE WAIT STATE I/O OUT FDCON,AL MOV AL,AH ;RESTORE CONTROLLER STATUS ENDIF WR2072: RET ;* DONE WITH 207 ; ; ENTRY: NONE ; EXIT: NONE ; USES: AL ; DONE207: MOV AL,PHYSID ;SAVE SIDE SELECT VALUE CMP BUFERR[BX],0 ;Q. DID ERROR OCCUR JZ DONE2071 ; BR IF NOT MOV AL,FDFSS1 DONE2071: MOV SIDE207,AL MOV Z207DSEL,Z207DSELV ;SET DESELECT VALUE RET ;* SET UP DEVICE ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: (BP)=ADDRESS OF DPE ; 'PHYTRK'=PHYSICAL TRACK # ; 'PHYSID'=PHYSICAL SIDE # ; 'SECCNT'=# SECTORS PER TRACK ; 'COUNT'=# BYTES PER SECTOR ; DRIVE IS SELECTED ; USES: AX,BP,SI ; SET207: MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE ; COMPUTE PHYSICAL TRACK AND SIDE VALUES MOV AL,BYTE PTR BUFTRK[BX] ;GET CP/M TRACK # MOV PHYSID,0 ;ASSUME SIDE 0 MOV PHYSIDN,0 TEST DPEFLAG[BP],DPE2S JZ SET2071A ;BR IF NOT DOUBLE SIDED MEDIA SHR AL,1 ;DIVIDE TRACK # BY 2 JNC SET2071A ;EVEN TRACKS ON SIDE 0 MOV PHYSID,FDFSS1 ; ODD TRACKS ON SIDE 1 MOV PHYSIDN,1 SET2071A: MOV PHYTRK,0 ;INSURE HIGH ORDER BYTE IS 0 MOV BYTE PTR PHYTRK,AL ;SAVE PHYSICAL TRACK # ; CHECK FOR SPECIAL CASE OF 8" DRIVE, TRACK 0, SIDE 0 CMP BYTE PTR PHYTRK,0 ;CHECK IF TRACK 0 JNE SET2072 ; BR IF NOT CMP PHYSID,0 ;CHECK IF SIDE 0 JNE SET2072 ; BR IF NOT TEST DPEFLAG[BP],DPET0SD ;CHECK IF TRACK 0 SINGLE DENSITY JZ SET2072 ; BR IF NOT MOV SECCNT,26 ;26 PHYSICAL SECTORS PER TRACK MOV COUNT,128 ;128 BYTES PER PHYSICAL SECTOR JMPS SET2073 ; COMPUTE NUMBER OF SECTORS PER TRACK SET2072: MOV SI,DPEDPB[BP] MOV AX,DPBSPT[SI] DIV DPERPS[BP] MOV SECCNT,AL ; COMPUTE NUMBER OF BYTES PER SECTOR MOV AL,128 MUL DPERPS[BP] MOV COUNT,AX ; SET2073: CALL DS207 ;SELECT DRIVE ; SET TRACK REGISTER IN CONTROLLER MOV AL ,DPETRK[BP] ;GET TRACK POSITION OUT FDTRK,AL ;SET TRACK REGISTER TEST AL,DPEUNK ;CHECK IF UNKNOWN JZ SET2074 ; BR IF KNOWN CALL RST207 ;RESTORE HEAD ; SET2074: RET ;* SET I/O RETRY COUNTER ; ; ENTRY: NONE ; EXIT: 'RETRIES' SET ; USES: NONE ; SRC207: MOV RETRIES,Z207MRC ;ASSUME MAX # TEST DSKOP,DSKOPRA+DSKOPS ;CHECK IF SPECIAL CASE JZ SRC2071 ; BR IF NOT MOV RETRIES,4 ;ALLOW ONLY 4 RETRIES SRC2071: RET ;* DRIVE SELECT ; ; ENTRY: NONE ; EXIT: DRIVE SELECTED AND UP TO SPEED ; USES: AX,CX ; DS207: MOV HLDDLYF,0 ;ASSUME ZERO DELAY MOV Z207DSEL,0 ;ZERO DESELECT TIMER ; FORM CONTROL WORD MOV AL,DPEUNIT[BP] ;GET UNIT SELECT FROM DPE OR AL,CONDSEN ;DRIVE SELECT ENABLE TEST DPEFLAG[BP],DPEDD ;Q. DOUBLE DENSITY JZ DS2070 ; BR IF NOT CMP BYTE PTR PHYTRK,0 ;CHECK FOR SPECIAL CASE JNE DS2071 ; WHERE TRACK 0 SIDE 0 CMP PHYSID,0 ; SINGLE DENSITY WHILE THE JNE DS2071 ; REST IS DOUBLE DENSITY TEST DPEFLAG[BP],DPET0SD JZ DS2071 ;BR IF NOT SPECIAL CASE DS2070: OR AL,CONSD ;SET FOR SINGLE DENSITY ; DS2071: MOV AH,AL ;(AH)=NEW CONTROL WORD TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELONOID JZ DS2071A ; BR IF NOT AND AL,CONDSEN+CONDS8+CONDS ;ISOLATE DRIVE SELECT BITS IN NEW MOV CL,DEVCTL ;ISOLATE DRIVE SELECT AND CL,CONDSEN+CONDS8+CONDS ; BITS IN OLD CONTROL WORD CMP AL,CL ;Q. SAME DRIVE STILL SELECTED JE DS2071A ; BR IF YES IN AL,FDTRK ;NEW DRIVE SELECTED - CAUSE 1797 OUT FDDAT,AL ; TO RESET HEAD LOAD DELAY TIMER MOV AL,FDCSEK ; BY DOING ZERO LENGTH SEEK WITH CALL WAIT207 ; HEAD UNLOADED MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O MOV Z207HUD,Z207HUDV DS2071A: TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELENOID JZ DS2071C ; BR IF NOT DS2071B: CMP Z207HUD,0 ; WAIT FOR HEAD UNLOAD DELAY TIME JNE DS2071B DS2071C: TEST AH,CONDS8 ;CHECK IF SELECTING 8" DRIVE JNZ DS2075 ; BR IF 8" ; SELECT 5 1/4" DRIVE AND AH,NOT CONPC ;ASSUME PRE-COMP TEST DPEFLAG[BP],DPE96T ;Q. 96 TPI DRIVE JNZ DS2072 ; BR IF YES CMP BYTE PTR PHYTRK,23 ;Q. TRACK >= 23 ON 48 TPI DRIVE JAE DS2072 ; BR IF YES OR AH,CONPC ;DON'T USE PRE-COMP DS2072: MOV AL,AH ;SELECT DRIVE OUT FDCON,AL ; HANDLE MOTOR START UP DELAY FOR 5 1/4" DRIVE TEST DSKOP,DSKOPWP+DSKOPI ;Q. WAIT FOR MOTOR UP TO SPEED ; JNZ DS2079 ; BR IF NO JZ $+5 JMP DS2079 MOV AL,DEVCTL ;CHECK IF A 5 1/4" DRIVE AND AL,CONDSEN+CONDS8 ; IS ALREADY SELECTED CMP AL,CONDSEN ; JE DS2079 ; BR IF YES JNE $+5 JMP DS2079 IN AL,FDAS ;SEE IF MOTOR STILL RUNNING TEST AL,ASMO ; JNZ DS2079 ; BR IF IT IS JZ $+5 JMP DS2079 MOV CX,250/TINTRVL+1 ;WAIT FOR 250 mS TEST DPESEK[BP],DPEMO ;CHECK IF FAST MOTOR UP TO SPEED JNZ DS2073 ; BR IF YES MOV CX,1000/TINTRVL+1 ;WAIT FOR 1 SEC DS2073: ADD CX,TICCNT DS2073A: CMP CX,TICCNT JNE DS2073A JMP DS2079 ; SELECT 8" DRIVE ; ; SINCE THE 1797 CHECKS THE DRIVE READY STATUS LINE BEFORE PLACING ; THE VALUE OF THE SIDE SELECT ON ITS OUTPUT PIN, IT MAY BE NECESSARY ; TO FORCE THE 1797 TO PLACE A SIDE SELECT VALUE ACCEPTABLE TO THE ; DRIVE BEFORE PRECEDING. THIS SITUATION ARISES WHEN ; 1. A PREVIOUS 1797 COMMAND SELECTED SIDE 1 ; 2. THE MEDIA IS NOT DOUBLE SIDED ; WHAT HAPPENS IS SOME DRIVES INDICATE DRIVE READY AS ; 1. MEDIA INSERTED ; 2. DOOR CLOSED ; 3. SIDE SELECTED IS AVAILABLE DS2075: MOV AL,AH ;SELECT DRIVE OUT FDCON,AL TEST DSKOP,DSKOPWP+DSKOPI+DSKOPRD ;Q. SKIP JNZ DS2079 ; BR IF YES CMP PHYSID,FDFSS1 ;Q. WISH TO USE SIDE 1 JE DS2078 IN AL,FDAS ;CHECK IF DOUBLE SIDED MEDIA TEST AL,AS2S JNZ DS2078 ; BR IF DOUBLE SIDED MEDIA CMP SIDE207,FDFSS1 ;CHECK IF SIDE 1 SELECTED PREVIOUSLY JNE DS2078 ; BR IF NOT XOR AL,AL ;DESELECT DRIVE OUT FDCON,AL PUSH AX MOV AL,FDCRDA+FDFDLF ;USE READ ADDRESS COMMAND OUT FDCMD,AL ; TO FORCE SIDE 0 SELECT MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE CALL WDLY DS2076: IN AL,FDSTA ;WAIT UNTIL 1797 GOES BUSY TEST AL,FDSBSY JZ DS2076 MOV AL,FDCFI+FDFINI ;TERMINATE COMMAND OUT FDCMD,AL MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE CALL WDLY DS2077: IN AL,FDSTA ;WAIT UNTIL 1797 GOES NOT BUSY TEST AL,FDSBSY JNZ DS2077 IN AL,FDDAT ;FLUSH ANY DATA IN 1797 POP AX TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELENOID JZ DS2077B ; BR IF NOT MOV Z207HUD,Z207HUDV ; WAIT FOR HEAD UNLOAD SETTLE TIME DS2077A: CMP Z207HUD,0 JNE DS2077A DS2077B: MOV AL,AH ;RESELECT DRIVE OUT FDCON,AL ; WAIT FOR MOTOR UP TO SPEED. DRIVE WILL INDICATE READY WHEN ; UP TO SPEED. THIS IS DONE TO ACCOMODATE DRIVES WITH DC MOTORS. DS2078: PUSH AX MOV AL,FDCFI+FDFINI ;FORCE TYPE 1 STATUS OUT FDCMD,AL MOV AX,(60+3)/4 ;DELAY TO GIVE STATUS A CHANCE CALL WDLY DS2078A: IN AL,FDSTA ;WAIT UNITL 1797 GOES NOT BUSY TEST AL,FDSBSY JNZ DS2078A MOV CX,1000/TINTRVL+1 ;WAIT 1 SEC MAX ADD CX,TICCNT DS2078B: CMP CX,TICCNT ;Q. TIME UP JE DS2078C ; BR IF YES IN AL,FDSTA TEST AL,FDSNRD ;Q. DRIVE READY JNZ DS2078B ; BR IF NOT DS2078C: POP AX ; DS2079: MOV DEVCTL,AH ;SAVE CONTROL REGISTER IMAGE RET ;* WWD207 - ISSUE COMMAND, WAIT FOR I/O COMPLETION, AND ; \ WAIT FOR MECHANICAL DELAY AFTER STEPPING ; ; ENTRY: (AL)=COMMAND ; EXIT: (AL)=CONTROLLER STATUS ; USES: AL ; WWD207: CALL WAIT207 ;DO I/O PUSH AX ;WAIT FOR MECHANICAL DELAY MOV AX,18*250 CALL WDLY TEST DPEUNIT[BP],CONDS8 ;WAIT A WHILE FOR DRIVE TO BE READY JZ WWD2073 ; THIS IS DONE FOR ZENITH PUSH CX ; 8" DRIVES MOV CX,200/TINTRVL+1 ADD CX,TICCNT WWD2071: CMP CX,TICCNT JE WWD2072 IN AL,FDSTA TEST AL,FDSNRD JNZ WWD2071 WWD2072: POP CX WWD2073: POP AX RET ;* WAIT207 - ISSUE COMMAND AND WAIT FOR I/O COMPLETION ; ; ENTRY: (AL)=COMMAND ; EXIT: (AL)=CONTROLLER STATUS ; USES: AL ; WAIT207: OUT FDCMD,AL ;ISSUE COMMAND PUSH AX ;WAIT AT LEAST 60uS MOV AX,(60+3)/4 ; BEFORE CHECKING STATUS CALL WDLY POP AX WAIT2071: IN AL,FDAS ;WAIT FOR IRQ TEST AL,ASIRQ JZ WAIT2071 WAIT2073: IN AL,FDSTA ;GET CONTROLLER STATUS TEST AL,FDSBSY ;WAIT FOR NOT BUSY JNZ WAIT2073 RET ;* CHECK IF TO DO RETRIES ; ; ENTRY: (AL)=CONTROLLER STATUS ; 'RETRIES'=RETRY COUNTER ; EXIT: PSW/C=RETRY STATUS (0=RETRY , 1=NO RETRY) ; USES: AL,CX,DI ; ; I/O RECOVERY PROCEDURE: ; 1) RETRY I/O OPERATION ; 2) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION ; 3) RETRY I/O OPERATION ; 4) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION ; 5) RETRY I/O OPERATION ; 6) RESTORE HEAD/RE-SEEK, THEN RETRY I/O OPERATION ; 7) RETRY I/O OPERATION ; 8) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION ; 9) RETRY I/O OPERATION ; 10) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION ; 11) RETRY I/O OPERATION ; 12) FLAG AS HARD ERROR ; ERR207: MOV ERRTYP,AL ;SAVE CONTROLLER STATUS AS ERROR TYPE TEST AL,FDSNRD+FDSWPV ;CHECK FOR NOT READY OR WRITE PROTECT ; JNZ ERR2079 ; BR IF YES - NO RETRIES JZ $+5 JMP ERR2079 TEST DSKOP,DSKOPR+DSKOPW ;Q. READ/WRITE OPERATION JZ ERR2070 ; BR IF NOT TEST AL,FDSRNF ;Q. RNF ERROR JZ ERR2070 ; BR IF NOT CMP RETRIES,Z207MRC ;Q. 1ST TRY JNE ERR2070 ; BR IF NOT PUSH HSTPTR ;TRY READING HEADER AT OTHER DENSITY PUSH HSTPTR+2 XOR DEVCTL,CONSD MOV AL,DEVCTL OUT FDCON,AL LEA DI,RDABUF CALL RDA207 POP HSTPTR+2 POP HSTPTR PUSH AX XOR DEVCTL,CONSD MOV AL,DEVCTL OUT FDCON,AL POP AX TEST AL,FDSRNF ;Q. RNF ERROR JZ ERR2079 ; BR IF NOT -- SOMEONE PROBABLY SWAPPED ; DISK THAT IS DIFFERENT DENSITY ERR2070: TEST DSKOP,DSKOPS ;IF NOT DOING A SELECT OPERATION JNZ ERR2071 INC SECNT ; BUMP SOFT ERROR COUNTER ERR2071: DEC RETRIES ;UPDATE RETRY COUNTER JZ ERR2079 ; BR IF EXHAUSTED RETRIES MOV AL,RETRIES CMP AL,6 JA ERR2072 SUB AL,6 ERR2072: JNZ ERR2073 ;BR IF NOT TIME TO DO RESTORE HEAD CALL RST207 ;RESTORE HEAD BEFORE TRYIN_G AGAIN JMPS ERR2077 ERR2073: CMP AL,4 ;CHECK IF TIME TO STEP OUT JNE ERR2074 ; BR IF NOT DEC BYTE PTR PHYTRK ;DECREMENT TO NEXT TRACK JS ERR2073A ; BR IF BEFORE TRACK 0 CALL SDT207 ; OTHERWISE STEP OUT ERR2073A: INC BYTE PTR PHYTRK ;RESTORE DESIRED TRACK JMPS ERR2077 ERR2074: CMP AL,2 ;CHECK IF TIME TO STEP IN JNE ERR2078 ; BR IF NOT MOV AL,NTRK837-1 ;GET MAXIMUM TRACK # TEST DPEUNIT[BP],CONDS8 JNZ ERR2074A MOV AL,NTRKD37-1 TEST DPEFLAG[BP],DPE96T JNZ ERR2074A MOV AL,NTRKS37-1 ERR2074A: INC BYTE PTR PHYTRK ;INCREMENT TO NEXT TRACK CMP AL,BYTE PTR PHYTRK ;CHECK IF MAX TRACK # >= NEXT TRACK JB ERR2074B ; BR IF IT IS CALL SDT207 ; OTHERWISE STEP IN ERR2074B: DEC BYTE PTR PHYTRK ;RESTORE DESIRED TRACK ERR2077: CALL SDT207 ;SEEK DESIRED TRACK ERR2078: CLC ;INDICATE TRY AGAIN RET ERR2079: MOV BUFERR[BX],1 ;SET ERROR FLAG MOV AL,ERRTYP ;RECOVER CONTROLLER STATUS TEST DSKOP,DSKOPR+DSKOPW ;IF DOING READ OR WRITE OPERATION JZ ERR2079B MOV DI,BUFERRF[BX] ; PLACE IN ERROR ARRAY ADD DI,PHYSEC MOV [DI],AL JMPS ERR2079D ERR2079B: TEST DSKOP,DSKOPF ;Q. FORMAT OPERATION JZ ERR2079C ; BR IF NO TEST DEVCTL,CONDS8 ;Q. 8" DRIVE JZ ERR2079C ; BR IF NOT CMP PHYTRK,0 ;Q. TRACK 0 JNE ERR2079C ; BR IF NOT CMP PHYSID,FDFSS1 ;Q. SIDE 1 JNE ERR2079C ; BR IF NOT CMP ERRTYP,FDSNRD ;Q. NOT READY ERROR JE ERR2079E ; BR IF YES ERR2079C: CALL ERRRPT ; OTHERWISE REPORT ERROR IMMEDIATELY ERR2079D: TEST DSKOP,DSKOPS ;IF NOT DOING A SELECT OPERATION JNZ ERR2079E INC HECNT ; COUNT HARD ERROR ERR2079E: STC ;INDICATE DON'T TRY AGAIN RET ;* RESTORE HEAD ; ; ENTRY: NONE ; EXIT: (AL)=CONTROLLER STATUS ; USES: AX ; RST207: MOV DPETRK[BP],0 ;INDICATE TRACK # 0 TEST DPESEK[BP],DPEFS ;Q. CAN DRIVE FAST STEP JZ RST2071 ; BR IF NOT MOV AL,DEVCTL ;SET UP FAST STEP OR AL,CON5FS OUT FDCON,AL RST2071: MOV AL,DPESEK[BP] ;GET STEP RATE AND AL,FDFSRM OR AL,FDCRST ;RESTORE HEAD COMMAND CALL WWD207 ;DO RESTORE TEST DPEFLG2[BP],DPEHLS ;Q. DRIVE HAS HEAD LOAD SELENOID JZ RST2071B ; BR IF NOT MOV Z207HUD,Z207HUDV ; WAIT FOR HEAD UNLOAD DELAY RST2071A: CMP Z207HUD,0 JNE RST2071A RST2071B: TEST DSKOP,DSKOPI ;Q. INIT OPERATION JZ RST2072 ; BR IF NOT TEST AL,FDSTK0 ;Q. AT TRACK 0 JZ RST2073 ; BR IF NOT RST2072: MOV AL,4 ;STEP IN 4 TRACKS TEST DSKOP,DSKOPI ;Q. INIT OPERATION JZ RST2072A ; BR IF NOT MOV AL,10 ; STEP IN 10 TRACKS RST2072A: CALL SDT2077 MOV AL,FDCRST+FDFHLB+FDFS30 ;RESTORE HEAD COMMAND CALL WWD207 ;DO RESTORE RST2073: MOV AH,AL ;SAVE CONTROLLER STATUS MOV AL,DEVCTL ;TURN OFF FAST STEP OUT FDCON,AL MOV AL,AH ;RESTORE CONTROLLER STATUS MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O RET ;* SEEK DESIRED TRACK ; ; ENTRY: 'PHYTRK'=TRACK # ; EXIT: NONE ; USES: AL ; SDT207: MOV AL,DPETRK[BP] ;GET CURRENT TRACK CMP AL,BYTE PTR PHYTRK ;CHECK AGAINST DESIRED TRACK JE SDT2072 ;ALREADY AT DESIRED TRACK TEST DPESEK[BP],DPEFS ;CHECK FOR FAST STEP JZ SDT2070 ; BR IF NOT MOV AL,DEVCTL ;ENABLE FAST STEP OR AL,CON5FS OUT FDCON,AL SDT2070: CALL SDT2076 ;DO SEEK TEST DPEFLAG[BP],DPE48RO ;CHECK IF 48TPI R/O MEDIA JZ SDT2071 ; BR IF NOT -- NO NEED TO DOUBLE STEP MOV AL,DPETRK[BP] ;GO THROUGH SEEK PROCEDURE AGAIN A SECOND TIME OUT FDTRK,AL ;RESET CONTROLLER'S TRACK REG CALL SDT2076 ;DO 2ND SEEK SDT2071: MOV AL,BYTE PTR PHYTRK ;OUTPUT DESIRED TRACK TO TRACK REG OUT FDTRK,AL ; THIS IS DONE IN CASE SEEK ABORTED % ; WHEN IT TRIED TO STEP TO NEGATIVE ; TRACK LEAVING TRACK REGISTER M; CONTAINING 0 MOV DPETRK[BP],AL ;UPDATE IN MEMORY TRACK VALUE MOV AL,DEVCTL ;RESTORE CONTROL REGISTER OUT FDCON,AL ; INCASE I WAS FAST STEPPING SDT2072: MOV HLDDLYF,FDFDLF ;USE DELAY FOR NEXT I/O RET ; DO SEEK SDT2076: MOV AL,BYTE PTR PHYTRK ;TELL CONTROLLER DESIRED TRACK SDT2077: OUT FDDAT,AL M OV AL,DPESEK[BP] ;GET STEP RATE AND AL,FDFSRM OR AL,FDCSEK+FDFHLB ; OR IN COMMAND JMP WWD207 ;DO I/O + MECHANICAL DELAY 9; RET VIA WDD207 ;* WAIT ~1.5 mS BEFORE STEPPING ; ; ENTRY: NONE ; EXIT: NONE ; USES: NONE ; WBS207: PUSH AX MOV AX,250*3/2+1 CALL WDLY POP AX RET X207 EQU OFFSET $ DSEG ORG X207 Z207DSEL DW 0 ;DRIVE DESELECT TIMER SLOT Z207HUD DW 0 ;HEAD UNLOAD DELAY TIMER SLOT DL207 RB 0 ;DEFAULT LABEL FOR 5 1/4" DB 0,DPEDD,0,4,8,0,0,0,0 DW 32 DB 3,7,0 DW 155,63,00C0H,16,1 IF (OFFSET $ - OFFSET DL207) NE (LABCS-LABEL) %: 5 1/4" DEFAULT LABEL IS NOT CORRECT LENGTH ENDIF X2071 EQU OFFSET $ CSEG ORG X2071  I ;** Z217 EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST WINSPT EQU 18 ;# PHYSICAL SECTORS PER TRACK WICSZ EQU 512 ;CELL SIZE USED ;* PORT ASSIGNMENTS WIPBASE EQU 0AEH ;BASE PORT WIPCMD EQU WIPBASE+0 ; COMMAND WIPSTAT EQU WIPBASE+0 ; HARDWARE STATUS WIPRES EQU WIPBASE+1 ; RESET WIPINTA EQU WIPBASE+1 ; INTERRUPT ACKNOWLEDGE/HARDWARE STATUS ;* HARDWARE STATUS REGISTER WISINT EQU 10% B ;INTERRUPT PENDING WISBUSY EQU 010 B ;BUSY WISBM EQU 0010b B ;BURST MODE WISTMA EQU 00010000B ;TMA IN PROGRESS WISERR EQU 00001000B ;ERROR WISIERR EQU 0) 100B ;IMMEDIATE MODE ERROR WISPAUS EQU 0 10B ;PAUSED WISDONE EQU 01B ;DONE ;* DIRECT MODE COMMANDS WISETUP EQU 08H ;SETUP WIEXEC EQU 10H ;EXECUTE WIPAUS EQU 18H ;PAUSE WICONT EQU 20H ;CONTINUE ;* CONTROL BLOCK COMMANDS WIRECAL EQU 00H ;RECALIBRATE WISTAT EQU 01H ;STATUS WIWRL EQU 10H ;WRITE LOGICAL WIRDL EQU 11H ;READ LOGICAL WISEKL EQU 13H ;SEEK LOGICAL WIFMTD EQU 20H ;FORMAT DRIVE WIFMTT EQU 21H ;FORMAT TRACK WISDP EQU 22H ;SET DRIVE PARAMETERS WIWRA EQU 30H ;WRITE ABSOLUTE WIRDA EQU 31H ;READ ABSOLUTE WISEKA EQU 33H ;SEEK ABSOLUTE ;* FORMAT OF COMMANDS ; TYPE 0 & 1 ORG 0 WI01BLK RB 0 WI01OP RB 1 ;COMMAND OP CODE WI01DHS RB 1 ;BIT 7-5 -- DRIVE SELECT 4 ; 4-0 -- HIGH BYTE OF LOG SECTOR # WI01D EQU 1110' B ; DRIVE SELECT MASK WI01HS EQU 0001 B ; HIGH BYTE OF LOG SECTOR # MASK WI01MS RB 1 ;MIDDLE BYTE OF LOGICAL SECTOR # WI01LS RB 1 ;LOW BYTE OF LOGICAL SECTOR # WI01SC RB 1 ;SECTOR COUNT WI01HT RB 1 ;HIGH BYTE OF DATA TMA ADDRESS WI01MT RB 1 C ;MIDDLE BYTE OF DATA TMA ADDRESS WI01LT RB 1 ;LOW BYTE OF DATA TMA ADDRESS WI01HN RB 1 ;HIGH BYTE OF NEXT COMMAND ADDRESS WI01MN RB 1 ;MIDDLE BYTE OF NEXT COMMAND ADDRESS WI01LN RB 1 ;LOW BYTE OF NEXT COMMAND ADDRESS WI01FLG RB 1 ;FLAGS WI01EEC RB 1 ;ERROR CODE WI01EDH RB 1 ;BIT 7-5 -- DRIVE SELECT 6 ; 4-0 -- HIGHT BYTE OF LOG SECTOR # WI01ED EQU 1110. B ; ERROR DRIVE SELECT MASK WI01EHS EQU 0001pB ; ERROR HIGH BYTE OF LOG SECTOR # MASK WI01EMS RB 1 ;ERROR MIDDLE BYTE OF LOGICAL SECTOR # WI01ELS RB 1 ;ERROR LOW BYTE OF LOGICAL SECTOR # WI01BKL EQU OFFSET $ - OFFSET WI01BLK IF WI01BKL NE 16 %: TYPE 0 & 1 COMMAND BLOCK IS WRONG LENGTH ENDIF ; TYPE 2 ORG 0 WI2BLK RB 0 WI2OP RB 1 ;COMMAND OP CODE WI2DH RB 1 ;BIT 7-5 -- DRIVE SELECT & ; 2-0 -- (MAX) HEAD # WI2D EQU 1110" B ; DRIVE SELECT MASK WI2H EQU 0111B ; HEAD # MASK WI2HMC RB 1 ;HIGH BYTE OF MAX CYLINDER # WI2LMC RB 1 ;LOW BYTE OF MAX CYLINDER # WI2HRWC RB 1 ;HIGH BYTE OF RWC CYLINDER # WI2LRWC RB 1 ;LOW BYTE OF RWC CYLINDER # WI2HPC RB 1 ;HIGH BYTE OF PRE-COMP CYLINDER # WI2LPC RB 1 ;LOW BYTE OF PRE-COMP CYLINDER # WI2SR RB 1 ;STEP RATE (LSB = 20uS) WI2ECC RB 1 ;ECC SPAN WI2CSIF RB 1 ;BIT 6 -- CELL SIZE + ; 4-0 -- INTERLEAVE FACTOR WI2CS EQU 010! B ; CELL SIZE MASK WI2CS5 EQU 09 B ; CELL SIZE = 512 BYTES/LOG SECTOR WI2CS1K EQU 0108 B ; CELL SIZE = 1024 BYTES/LOG SECTOR WI2IF EQU 0001 B ; INTERLEAVE FACTOR MASK WI2FC RB 1 ;FILL CHARACTER WI2EEC RB 1 ;ERROR CODE WI2EHS RB 1 ;BIT 7-5 -- ERROR HEAD # ) ; 4-0 -- ERROR SECTOR # WI2EH EQU 1110& B ; ERROR HEAD # MASK WI2ES EQU 0001JB ; ERROR SECTOR # MASK WI2EHC RB 1 ;ERROR HIGH BYTE OF CYLINDER # WI2ELC RB 1 ;ERROR LOW BYTE OF CYLINDER # WI2BLKL EQU OFFSET $ - OFFSET WI2BLK IF WI2BLKL NE 16 %: TYPE 2 COMMAND BLOCK IS WRONG LENGTH ENDIF ; TYPE 3 ORG 0 WI3BLK RB 0 WI3OP RB 1 ;COMMAND OP CODE WI3DH RB 1 ;BIT 7-5 -- DRIVE SELECT ; 2-0 -- HEAD # WI3D EQU 1110" B ; DRIVE SELECT MASK WI3H EQU 0111B ; HEAD # MASK WI3HC RB 1 ;HIGH BYTE OF CYLINDER # WI3LC RB 1 ;LOW BYTE OF CYLINDER # WI3S RB 1 ;SECTOR # WI3HT RB 1 ;HIGH BYTE OF DATA TMA ADDRESS WI3MT RB 1 ;MIDDLE BYTE OF DATA TMA ADDRESS WI3LT RB 1 ;LOW BYTE OF DATA TMA ADDRESS WI3HN RB 1 ;HIGH BYTE OF NEXT COMMAND ADDRESS WI3MN RB 1 ;MIDDLE BYTE OF NEXT COMMAND ADDRESS WI3LN RB 1 ;LOW BYTE OF NEXT COMMAND ADDRESS WI3FLG RB 1 ;FLAGS WI3EEC RB 1 ;ERROR CODE WI3EHS RB 1 ;BIT 7-5 -- ERROR HEAD # ) ; 4-0 -- ERROR SECTOR # WI3EH EQU 1110& B ; ERROR HEAD # MASK WI3ES EQU 0001 B ; ERROR SECTOR # MASK WI3EHC RB 1 ;ERROR HIGH BYTE OF CYLINDER # WI3ELC RB 1 ;ERROR LOW BYTE OF CYLINDER # WI3BLKL EQU OFFSET $ - OFFSET WI3BLK IF WI3BLKL NE 16 %: TYPE 3 COMMAND BLOCK IS WRONG LENGTH ENDIF ; COMMAND BLOCK FLAG BYTE WIFINTE EQU 10$ B ;INTERRUPTS ENABLED WIFBM EQU 010' B ;USE BURST MODE TMA WIFIPCC EQU 00103 B ;IGNORE PAUSE AND CONTINUE COMMANDS WIFIDR EQU 0$ 100B ;DISABLE RETRIES WIFDECC EQU 0 10B ;DISABLE ECC WIFCHN EQU 0 1B ;CHAIN NEXT COMMAND IMMEDIATELY ;* FORMAT OF STATUS RETURNED BY 01 COMMAND ORG 0 WISBLK RB 0 WISFLG RB 1 ;FLAG BYTE WISDR EQU 0* 100B ; BIT 2 -- DRIVE READY WISACC EQU 0 10B ;  1 -- ACCESSED WISSC EQU 0 1B ; l0 -- SEEK COMPLETE WISHMC RB 1 ;HIGH BYTE OF MAX CYLINDER # WISLMC RB 1 ;LOW BYTE OF MAX CYLINDER # WISHRWC RB 1 ;HIGH BYTE OF RWC CYLINDER # WISLRWC RB 1 ;LOW BYTE OF RWC CYLINDER # WISHPC RB 1 ;HIGH BYTE OF PRE-COMP CYLINDER # WISLPC RB 1 ;LOW BYTE OF PRE-COMP CYLINDER # WISHCC RB 1 ;HIGH BYTE OF CURRENT CYLINDER # WISLCC RB 1 ;LOW BYTE OF CURRENT CYLINDER # WISSR RB 1 ;STEP RATE (LSB = 20uS) RB 1 ;RESERVED WISIF RB 1 ;INTERLEAVE FACTOR WISCS RB 1 ;CELL SIZE WISCS5 EQU 1 ; = 512 BYTES/LOG SECTOR WISCS1K EQU 2 ; = 1024 BYTES/LOG SECTOR WISMH RB 1 ;MAX HEAD # WISFfC RB 1 ;FILL CHARACTER RB 1 ;RESERVED WISBLKL EQU OFFSET $ - OFFSET WISBLK IF WISBLKL NE 16 %: STATUS BLOCK IS WRONG LENGTH ENDIF ;* ERROR CODES WIENE EQU 00H ;NO ERROR WIEDNR EQU 01H ;DRIVE NOT READY WIENSC EQU 02H ;NO SEEK COMPLETE WIENT0 EQU 03H ;NO TRACK 0 WIENI EQU 04H ;NO INDEX WIENDS EQU 05H ;NO DRIVE SELECT WIEHNF EQU 10H ;HEADER ADDRESS MARK NOT FOUND WIESEK EQU 11H ;SEEK ERROR (BAD CYLINDER # IN HEADER) WIESNF EQU 12H ;SECTOR NOT FOUND WIEECCH EQU 13H ;ECC ERROR IN HEADER WIEDNF EQU 14H ;DATA ADDRESS MARK NOT FOUND WIENECC EQU 15H ;NONCORRECTABLE ECC ERROR IN DATA FIELD WIEECC EQU 16H ;CORRECTABLE ECC ERROR IN DATA FIELD WIEWF EQU 17H ;WRITE FAULT WIEIOP EQU 20H ;ILLEGAL OP CODE WIEIDA EQU 21H ;ILLEGAL DISK ADDRESS WIEFMTP EQU 22H ;FORMAT PROTECTED WIEWRP EQU 23H ;WRITE PROTECTED WIEMISC EQU 30H ;MISCELLANEOUS ERROR WIEDIAG EQU 40H ;ERROR DURING DIAGNOSTIC WIEPNA EQU 80H ;PARTION NOT ASSIGNED WIESNWP EQU 81H ;SECTOR NOT WITHIN PARTITION ;* CP/M RELATED VALUES WIRPS EQU WICSZ/128 ;CP/M RECORDS PER SECTOR WIRPT EQU WIRPS*WINSPT ;CP/M RECORDS PER TRACK WINST EQU 1 ;# OF SYSTEM TRACKS WINSYS EQU WINST*WINSPT ;# SECTORS IN SYSTEM TRACK(S) WIMIN EQU 1024/WICSZ*64+WINSYS ;MINIMUM # USEABLE SECTORS WIMAX EQU 1024/WICSZ*8*1024+WINSYS ;MAX # USEABLE SECTORS  ;*** Z217 DEVICE DRIVER ; ; * * * N O T E * * * ; ; THIS DRIVE ASSUMES A CELL SIZE OF 512 BYTES WITH 18 SECTORS PER TRACK. ; ; ONLY UNIT 0 IS HANDLED. ; ; ALTHOUGH THE CONTROLLER PROVIDES FOR 21 BIT LOGICAL SECTOR NUMBERS, ; THIS DRIVER ONLY HANDLES 16 BIT LOGICAL SECTOR NUMBERS. THEREFORE, ; THE MAXIMUM SIZE OF DISK IS 65536 SECTORS (0-FFFFH). ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; >"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;** DRIVER ENTRY JUMP VECTORS ; DRVR217: JMP SEL217 ;SELECT JMP RDT217 ;READ TRACK JMP WRT217 ;WRITE TRACK JMP MNT217 ;MOUNT JMP FMT217 ;FORMAT JMP WPC217 ;WRITE PROTECT CHECK ;** INITIALIZE DRIVE TABLES ; ; ENTRY: NONE ; EXIT: NONE ; USES: ALL ; IN217: ; FILL IN COMMAND BLOCK LEA DI,Z217BLK ;ADDRESS OF NEXT COMMAND MOV AX,DS MOV ES,AX CALL TMA217 MOV AL,Z217BLK+OFFSET WI01HT MOV Z217BLK+OFFSET WI01HN,AL MOV AL,Z217BLK+OFFSET WI01MT MOV Z217BLK+OFFSET WI01MN,AL MOV AL,Z217BLK+OFFSET WI01LT MOV Z217BLK+OFFSET WI01LN,AL ; CHECK IF CONTROLLER IS PRESENT LEA DI,Z217BLK ;ATTEMPT TO ISSUE SETUP COMMAND MOV AX,DS MOV ES,AX CALL SUP217 JC IN2174 ; BR IF ERROR ; READ SBC AND SET DRIVE PARAMETERS LES DI,DWORD PTR HEADER+OFFSET BUFBUF ;GET BUFFER ADDRESS CALL TMA217 CALL WAIT2171 ;EXECUTE READ COMMAND TEST AL,WISERR ;Q. ERROR JNZ IN2174 ; BR IF ERROR LES DI,DWORD PTR HEADER+OFFSET BUFBUF ;ADDRESS OF SET DRIVE ADD DI,OFFSET SBCSDP ; PARAMETERS COMMAND CALL SUP217 JC IN2174 ; BR IF ERROR CALL WAIT2171 ;EXECUTE COMMAND TEST AL,WISERR ;Q. ERROR JNZ IN2174 ; BR IF ERROR LEA DI,Z217BLK ;ADDRESS FOR REST OF DRIVER MOV AX,DS 0MOV ES,AX CALL SUP217 JNC IN2175 ; BR IF NO ERROR ; MARK DRIVE AS IMAGINARY IN2174: MOV CX,2 ;# OF Z217 DRIVES LEA BP,DPEBASE+DPEL*4 ;START ADDRESS OF Z217 DPE'S IN21741: OR DPEFLG2[BP],DPEIMG ;FLAG DRIVE AS IMAGINARY ADD BP,DPEL ;BUMP POINTER LOOP IN21741 ;LOOP AND MARK ALL DRIVES ; FILL IN DPE TABLES / DISK MAP TABLE IN2175: MOV CH,2 ;# DRIVES MOV CL,0 ;STARTING UNIT # MOV DH,4 ;STARTING DRIVE MAP # CALL CBTFIL ;DO FILL ; ASSIGN PARTITION IF BOOT UNIT XOR AX,AX MOV ES,AX MOV ES,ES: .MTRDSEG ;GET ADDRESS OF MONITOR DATA AREA CMP ES: MTRBI,2 ;Q. Z217 BOOTED JNE IN2176 ; BR IF NOT LEA BP,DPEBASE+4*DPEL ;GET ADDRESS OF 1ST DPE FOR Z217 OR DPEFLAG[BP],DPEASGN ;SHOW PARTITION ASSIGNED MOV AX,Z217BP MOV WORD PTR DPETRK[BP],AX ;SET BEGINNING SECTOR OF PARTITION MOV AX,Z217EP MOV WORD PTR DPEUPB[BP],AX ;SET LAST SECTOR # OF PARTITION IN2176: RET ;** SELECT DRIVE FOR 1ST LOGIN ; ; ENTRY: 'PHYDPE'=ADDRESS OF DPE FOR DRIVE ; (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'PHYDPE'=STATUS ; 0=ERROR , OTHERWISE SAME AS ON ENTRY ; USES: SI,DI ; SEL217: OR DSKOP,DSKOPS ;INDICATE SELECT OP IN PROGRESS MOV BUFTRK[BX],0 ;READ LABEL CALL SET217 LES DI,DWORD PTR BUFBUF[BX] CALL RDS217 CMP BUFERR[BX],0 ;Q. ERROR JNZ SET2179 ; BR IF YES LES SI,DWORD PTR BUFBUF[BX] ;CHECK CHECKSUM OF LABEL ADD SI,LABEL CALL CHKLAB JNZ SET2179 ; BR IF ERROR LES SI,DWORD PTR BUFBUF[BX] ;CHECK IF LABEL'S BEGINNING OF MOV DI,ES: WORD PTR LABHTH+(OFFSET DPETRK)-(OFFSET DPEHTH) [SI] CMP DI,WORD PTR DPETRK[BP] ;PARTITION SECTOR # MATCHES DRIVE TABLE JNE SET2179 ; BR IF NOT MOV DI,ES: WORD PTR LABHTH+(OFFSET DPEUPB)-(OFFSET DPEHTH) [SI] CMP DI,WORD PTR DPEUPB[BP] ;CHECK IF LABEL'S LAST SECTOR # OF ; PARTITION MATCHES DRIVE TABLE JNE SET2179 ; BR IF NOT MOV AL,ES: LABHTH+(OFFSET DPERPAB)-(OFFSET DPEHTH) [SI] MOV DPERPAB[BP],AL ;CP/M RECORDS PER ALLOCATION BLOCK ADD SI,OFFSET LABDPB ;UPDATE DISK PARAMETER BLOCK VALUES MOV DI,DPEDPB[BP] MOV CX,DPBL CLD CALL EXDSES REP MOVSB CALL EXDSES SET2178: AND DSKOP,NOT DSKOPS ;INDICATE SELECT OP COMPLETE RET SET2179: MOV PHYDPE,0 ;INDICATE ERROR JMPS SET2178 ;** READ TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]=STATUS ; 0=NO ERROR , 1=ERROR ; USES: DI ; RDT217: CALL SET217 ;SETUP LES DI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS RDT2171: CMP PREREAD,0 ;Q. DOING PREREAD JNE RDT2172 ; BR IF YES CMP BUFERR[BX],0 ;Q. ABORT JNE RDT2173 ; BR IF YES RDT2172: CALL RDS217 ;READ NEXT SECTOR RDT2173: ADD DI,WICSZ ;BUMP BUFFER POINTER INC PHYSEC ;BUMP 'PHYSEC' CMP PHYSEC,WINSPT ;Q. ALL SECTORS READ JNE RDT2171 ; BR IF NOT RET ;** WRITE TRACK ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=NO ERROR , 1=ERROR ; USES: AX,SI,DI ; WRT217: CALL SET217 ;SETUP LES DI,DWORD PTR BUFBUF[BX] ;BUFFER ADDRESS WRT2171: MOV SI,BUFSECF[BX] ;CHECK IF PHYSICAL SECTOR IS DIRTY ADD SI,PHYSEC TEST BYTE PTR [SI],1 JZ WRT2173 ; BR IF IT IS NOT MOV BYTE PTR [SI],0 ;CLEAR DIRTY SECTOR FLAG CMP BUFERR[BX],0 ;Q. ABORT JNE WRT2173 ; BR IF YES CALL WRS217 ;WRITE SECTOR WRT2173: ADD DI,WICSZ ;BUMP BUFFER POINTER TO NEXT SECTOR INC PHYSEC ;BUMP PHYSICAL SECTOR # CMP PHYSEC,WINSPT ;Q. ALL TRACK WRITTEN JNE WRT2171 ; BR IF NOT RET ;** MOUNT ; ; ENTRY: (BX)=POINTER TO BUFFER HEADER INFO ; EXIT: NONE ; USES: NONE ; MNT217: RET ;** FORMAT TRACK ; ; ENTRY: NONE ; EXIT: NONE ; USES: NONE ; FMT217: RET ;** WRITE PROTECT CHECK ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: 'BUFERR[BX]'=STATUS ; 0=R/W , 1=R/O ; USES: NONE ; WPC217: MOV BUFERR[BX],0 ;ALWAYS R/W RET ;* READ SECTOR ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # ; 'SEC217'=STARTING LOGICAL SECTOR # OF TRACK ; (DI),(ES)=BUFFER POINTER ; EXIT: NONE  ; USES: AL ; RDS217: OR DSKOP,DSKOPR ;INDICATE READ OP IN PROGRESS MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV Z217BLK+OFFSET WI01OP,WIRDL ;READ LOGICAL OP CODE CALL CLS217 ;CALCULATE LOGICAL SECTOR # JC RDS2172 ; BR IF ERROR CALL TMA217 ;CALCULATE DATA TMA ADDRESS CALL WAIT217 ;DO I/O TEST AL,WISERR ;Q. ERROR JZ RDS2173 ; BR IF NO ERROR RDS2172: CALL ERR217 ;REPORT ERROR CMP PREREAD,0 ;Q. IS THIS A PREREAD OPERATION JNE RDS2173 ; BR IF YES CALL ABTIGN ;HANDLE ABORT/IGNORE RDS2173: LES DI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPR ;INDICATE READ OP DONE RET ;* WRITE SECTOR ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # ; 'SEC217'=STARTING LOGICAL SECTOR # OF TRACK ; (DI),(ES)=BUFFER POINTER ; EXIT: NONE ; USES: AL ; WRS217: OR DSKOP,DSKOPW ;INDICATE WRITE OP IN PROGRESS MOV HSTPTR,DI ;SAVE BUFFER POINTER MOV HSTPTR+2,ES MOV Z217BLK+OFFSET WI01OP,WIWRL ;WRITE LOGICAL OP CODE CALL CLS217 ;CALCULATE LOGICAL SECTOR # JC WRS2172 ; BR IF ERROR CALL TMA217 ;CALCULATE DATA TMA ADDRESS CALL WAIT217 ;DO I/O TEST AL,WISERR ;Q. ERROR JZ WRS2173 ; BR IF NO ERROR WRS2172: CALL ERR217 ;REPORT ERROR CALL ABTIGN ;HANDLE ABORT/IGNORE WRS2173: LES DI,DWORD PTR HSTPTR ;RESTORE BUFFER POINTER AND DSKOP,NOT DSKOPW ;INDICATE WRITE OP DONE RET ;* EXECUTE COMMAND AND WAIT FOR I/O COMPLETION ; ; ENTRY: 'Z217BLK'=COMMAND BLOCK ; EXIT: (AL)=CONTROLLER HARDWARE STATUS ; USES: AL ; WAIT217: TEST DPEFLAG[BP],DPEASGN ;Q. PARTITION ASSIGNED JNZ WAIT2171 ; BR IF YES TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ WAIT2171 ; BR IF YES MOV AL,WISERR ;INDICATE ERROR MOV Z217BLK+OFFSET WI01EEC,WIEPNA RET WAIT2171: MOV AL,WIEXEC ;ISSUE EXECUTE COMMAND OUT WIPCMD,AL WAIT2172: IN AL,WIPSTAT ;WAIT FOR CONTROLLER TO BE DONE TEST AL,WISDONE JZ WAIT2172 RET ;* CALCULATE LOGICAL SECTOR # AND PLACE IN COMMAND BLOCK ; ; ENTRY: 'PHYSEC'=PHYSICAL SECTOR # FOR TRACK ; 'PHYTRK'=LOGICAL SECTOR # OF 1ST SECTOR OF TRACK ; EXIT: 'Z217BLK'=COMMAND BLOCK CONTAINS LOGICAL SECTOR # ; 'C' = 0 NO ERROR , 1=ERROR ; USES: AX ; ; LOGICAL SECTOR # = 'PHYTRK' + 'PHYSEC' ; CLS217: MOV AX,PHYTRK ADD AX,PHYSEC TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ CLS2171 ; BR IF YES CMP AX,WORD PTR DPETRK[BP] ;Q. SECTOR # WITHIN PARTITION JB CLS2172 ; BR IF NOT CMP AX,WORD PTR DPEUPB[BP] JA CLS2172 ; BR IF NOT CLC CLS2171: MOV Z217BLK+OFFSET WI01LS,AL MOV Z217BLK+OFFSET WI01MS,AH RET CLS2172: STC ;INDICATE ERROR MOV Z217BLK+OFFSET WI01EEC,WIESNWP MOV Z217BLK+OFFSET WI01EMS,AH MOV Z217BLK+OFFSET WI01ELS,AL RET ;* CALCULATE DATA TMA ADDRESS ; ; ENTRY: (ES)=DATA SEGMENT ; (DI)=DATA OFFSET ; EXIT: 'Z217BLK'=COMMAND BLOCK CONTAINS DATA TMA ADDRESS ; USES: AX,DL ; ; DATA TMA ADDRESS = (ES)*16 + (DI) ; TMA217: MOV AX,ES XOR DL,DL SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 SHL AX,1 RCL DL,1 ADD AX,DI ADC DL,0 MOV Z217BLK+OFFSET WI01HT,DL MOV Z217BLK+OFFSET WI01MT,AH MOV Z217BLK+OFFSET WI01LT,AL RET ;* COMMON SETUP ROUTINE ; ; ENTRY: (BX)=ADDRESS OF BUFFER HEADER INFO ; EXIT: 'PHYTRK'=LOGICAL SECTOR # OF 1ST SECTOR OF TRACK ; 'PHYSEC'=0 ; USES: AX,DX ; SET217: MOV BP,BUFDPE[BX] ;GET ADDRESS OF DPE MOV AX,BUFTRK[BX] ;CALCULATE LOGICAL SECTOR # MOV DX,WINSPT ; OF 1ST SECTOR ON TRACK MUL DX TEST DPEFLAG[BP],DPELSIO ;Q. LOGICAL SECTOR I/O JNZ SET2171 ; BR IF YES ADD AX,WORD PTR DPETRK[BP] ;ADJUST FOR BEGINING OF PARTITION SET2171: MOV PHYTRK,AX MOV PHYSEC,0 RET ;* ISSUE SETUP COMMAND TO CONTROLLER ; ; ENTRY: (DI),(ES)=COMMAND BLOCK ADDRESS ; EXIT: PSW/C 0=OK , 1=ERROR ; USES: AX ; SUP217: CALL TMA217 ;CONVERT ADDRESS TO 24 BITS MOV AX,10*250 ;SET MAXIMUM TIME FOR ALL TO HAPPEN CALL NWDLY ; TO 10 mS MOV AL,WISETUP ;ISSUE SETUP COMMAND OUT WIPCMD,AL SUP2172: CMP TIMEFLG,0 ;Q. TIME UP JNE SUP2174 ; BR IF YES IN AL,WIPSTAT ;INPUT HARDWARE STATUS TEST AL,WISBUSY ;Q. CONTROLLER BUSY JZ SUP2172 ; BR IF NOT MOV AL,Z217BLK+OFFSET WI01HT ;SEND HIGH ADDRESS BYTE OUT WIPCMD,AL MOV AL,Z217BLK+OFFSET WI01MT ;SEND MIDDLE ADDRESS BYTE OUT WIPCMD,AL MOV AL,Z217BLK+OFFSET WI01LT ;SEND LOW ADDRESS BYTE OUT WIPCMD,AL SUP2173: CMP TIMEFLG,0 ;Q. TIME UP JNE SUP2174 ; BR IF YES IN AL,WIPSTAT ;INPUT HARDWARE STATUS TEST AL,WISBUSY ;Q. STILL BUSY JNZ SUP2173 ; BR IF YES TEST AL,WISDONE ;Q. I/O DONE JZ SUP2173 ; BR IF NOT DONE ; RET ; SUP2174: STC ;INDICATE ERROR RET ;* ERROR REPORTING ; ; ENTRY: 'Z217BLK' CONTAINS ERROR INFORMATION ; EXIT: NONE ; USES: AL,CX,SI,DI ; ERR217: MOV BUFERR[BX],1 ;INDICATE ERROR MOV AL,Z217BLK+OFFSET WI01EEC ;GET ERROR CODE TEST DSKOP,DSKOPR+DSKOPW ;IF DOING READ OR WRITE OPERATION JZ ERR2177 MOV DI,BUFERRF[BX] ; PLACE IN ERROR ARRAY ADD DI,PHYSEC MOV [DI],AL JMPS ERR2178 ERR2177: CALL ERRRPT ; OTHERWISE REPORT ERROR IMMEDIATELY ERR2178: TEST DSKOP,DSKOPS ;Q. DOING 1ST TIME SELECT JNZ ERR2179 ; BR IF YES INC HECNT ;COUNT HARD ERROR ERR2179: RET ;* LOCAL DATA AREA FOR DRIVER WIX1 EQU OFFSET $ DSEG ORG WIX1 Z217BLK RB 0 ;COMMAND BLOCK DB WIRDL ; OP CODE DB 0 ; UNIT SELECT DB 0,0 ; LOGICAL SECTOR # DB 1 ; SECTOR COUNT DB 0,0,0 ; TMA ADDRESS DB 0,0,0 ; NEXT COMMAND ADDRESS DB 0 ; FLAGS DB 0,0,0,0 ; ERROR RETURN INFO IF (OFFSET $ - OFFSET Z217BLK) NE WI01BKL %: Z217BLK IS NOT CORRECT LENGTH ENDIF Z217BP RW 1 ;BEGINNING OF BOOT PARTITION Z217EP RW 1 ;END OF BOOT PARTITION ; WIX2 EQU OFFSET $ CSEG ORG WIX2 Y ;** DISK PARAMETER TABLE EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; DISK PARAMETER ENTRY DESCRIPTION ORG 0 DPEXLT RW 1 ;SECTOR TRANSLATE TABLE ADDRESS RW 3 DPEDIRB RW 1 ;DIRECTORY BUFFER ADDRESS DPEDPB RW 1 ;DISK PARAMETER BLOCK ADDRESS DPECSV RW 1 ;CHECKSUM VECTOR ADDRESS DPEALV RW 1 ;ALLOCATION VECTOR ADDRESS DPEHTH RB 8 ;HEATH EXTENSIONS DPEL EQU 24 ;LENGTH OF DISK PARAMETER ENTRY ; HEATH EXTENSIONS DPEFLAG EQU DPEHTH+0 ;FLAGS DPETYPE EQU 1110$ B ;BIT 7-5 = DEVICE TYPE DPENE EQU 0! B ; NON-EXISTENT DPEZ207 EQU 0010 B ; Z207 DPEZ217 EQU 010 B ; Z217 DPE48RO EQU 00010000B ;BIT 4 -- FOR Z207 ; 48 TPI MEDIA IN 96 TPI DRIVE (R/O) DPE96T EQU 00001000B ;BIT 3 -- 0=48 TPI DRIVE 1=96 TPI DRIVE DPEASGN EQU 00001000B ;BIT 3 -- FOR Z217 WINCHESTER DISK ;  0=UNASSIGNED A PARTITION ; $ 1=ASSIGNED A PARTITION DPET0SD EQU 06 100B ;BIT 2 -- 1=TRACK 0 IS SINGLE DENSITY DPEDD EQU 06 10B ;BIT 1 -- 0=SINGLE DENSITY 1=DOUBLE DPELSIO EQU 01 10B ;BIT 1 -- Z217 LOGICAL SECTOR I/O DPE2S EQU 03 1B ;BIT 0 -- 0=SINGLE SIDED 1=DOUBLE DPEPRIM EQU 0 1B ;BIT 0 -- Z217 PRIMARY DPE FOR UNIT DPEUNIT EQU DPEHTH+1 ;UNIT SELECT VALUE DPERPS EQU DPEHTH+2 ;CP/M RECORDS PER PHYSICAL SECTOR DPERPAB EQU DPEHTH+3 ;CP/M RECORDS PER ALLOCATION BLOCK DPETRK EQU DPEHTH+4 ;TRACK COUNTER DPEUNK EQU 10 B ; TRACK POSITION UNKNOWN DPELPB EQU DPEHTH+4 ;Z217 LOWER PARTITION BOUNDARY (LOG SECTOR #) DPESEK EQU DPEHTH+5 ;MOTOR SPEED AND SEEK SPEED ;BIT 3-0 = SEEK SPEED VALUE DPEFS EQU 010* B ;BIT 6 = FAST STEP FOR Z207 DPEMO EQU 10 B ;BIT 7 = MOTOR UP TO SP EED FLAG ; 0=1 SEC 1=250 MSEC DPEUPB EQU DPEHTH+6 ;Z217 UPPER PARTITION BOUNDARY + 1 DPEFLG2 EQU DPEHTH+6 ;2ND FLAG BYTE DPEHLS EQU 06 100B ;BIT 2 DRIVE HAS HEAD LOAD SELONOID DPEIMG EQU 0) 10B ;BIT 1 IMAGINARY DRIVE DPE96TM EQU 0:1B ;BIT 0 0=48 TPI MEDIA 1=96 TPI MEDIA DPELUN EQU DPEHTH+7 ;LAST LOGICAL UNIT MOUNTED DPELOG EQU 11110000B ; CP/M LOGICAL DRIVE NAME FOR THIS ENTRY DPEREAL EQU 00001111B ; FOR IMAGINARY DRIVE, LOGICAL DRIVE NAME ; FOR CORRESPONDING REAL DRIVE DPEMNT EQU 00001111B ; FOR REAL DRIVE, LOGICAL DRIVE NAME FOR ; CURRENLY MOUNTED DISK DPEHL EQU 8 ;LENGTH OF HEATH EXTENSION ; DISK PARAMETER BLOCK ORG 0 DPBSPT RW 1 ;SECTORS PER TRACK DPBBSH RB 1 ;BLOCK SHIFT FACTOR DPBBLM RB 1 ;BLOCK MASK DPBEXM RB 1 ;EXTENT MASK DPBDSM RW 1 ;TOTAL # OF BLOCKS - 1 DPBDRM RW 1 ;# OF DIRECTORY ENTRIES - 1 DPBAL0 RB 1 ;INITIAL AL0 VALUE DPBAL1 RB 1 ;INITIAL AL1 VALUE DPBCKS RW 1 ;SIZE OF DIRECTORY CHECK VECTOR DPBOFF RW 1 ;NUMBER OF SYSTEM TRACKS DPBL EQU 15 ;LENGTH OF DISK PARAMETER BLOCK y ;** Z-100 GENERAL DATA PORT DEFINITIONS ; ; HARDWARE IS A 6821 ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT ASSIGNMENTS GDPDATA EQU ZGDP+PIADATA ;DATA PORT A GDPDDRA EQU ZGDP+PIADDRA ;DATA DIRECTION PORT A GDPCTLA EQU ZGDP+PIACTLA ;CONTROL PORT A GDPDATB EQU ZGDP+PIADATB ;DATA PORT B GDPDDRB EQU ZGDP+PIADDRB ;DATA DIRECTION PORT B GDPCTLB EQU ZGDP+PIACTLB ;CONTROL PORT B ; CONTROL PORT A ASSIGNMENTS GDPCAV EQU PIAC12+PIAC23+PIADDAC ;INITIALIZATION VALUE LPENSI EQU PIAIRQ1 ;CA1 = LIGHT PEN STROBE  ; > INTERRUPT ON 0->1 VSYNCI EQU PIAIRQ2 ;CA2 = VERTICAL SYNC  ; ~ INTERRUPT ON 0->1 ; DATA DIRECTION PORT A ASSIGNMENTS GDPDDAV EQU 10101111B ; DATA PORT A ASSIGNMENTS PPRTM10 EQU 0& 11B ;PRINTER D1-D0 MASK PPRTSTB EQU 0 100B ;PRINTER STROBE (OUTPUT ACTIVE LOW) PPRTPRM EQU 00001000B ;PRINTER PRIME (OUTPUT ACTIVE LOW) VSYNC EQU 00010000B ;VERTICAL SYNC (INPUT ACTIVE HIGH) VSYNCE EQU 00107 B ;VERT SYNC TO CA2 (0=DISABLE, 1=ENABLE) LPEN EQU 0106 B ;LIGHT PEN SWITCH (INPUT ACTIVE HIGH) LPENSE EQU 10 B ;LIGHT PEN STROBE TO CA1 (0=DISABLE, 1=ENABLE) ; CONTROL PORT B ASSIGNMENTS GDPCBV EQU PIAC12+PIAC20+PIADDAC ;INITIALIZATION VALUE PRTACKI EQU PIAIRQ1 ;CB1 = PRINTER ACKNOWLEDGE  ; A NO INTERRUPT ON 0->1 PRTBSYI EQU PIAIRQ2 ;CB2 = PRINTER BUSY  ; K NO INTERRUPT ON 1->0 ; DATA DIRECTION PORT B ASSIGNMENTS GDPBDDV EQU 10 00B ; DATA PORT B ASSIGNMENTS PPRTBSY EQU 03 1B ;PRINTER BUSY (INPUT ACTIVE HIGH) PPRTFLT EQU 04 10B ;PRINTER FAULT (INPUT ACTIVE LOW) PPRTM72 EQU 1 00B ;PRINTER D7-D2 MASK \ ;** Z-MACHINE INTERRUPT ASSIGNMENTS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; S"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; MASTER 8259A ZINTMT EQU 0C0H ;BASE TRAP VECTOR # ZINTEI EQU 0 ;ERROR INTERRUPT ZINTPS EQU 1 ;PROCESSOR SWAP ZINTTIM EQU 2 ;TIMER ZINTSLV EQU 3 ;SLAVE 8259A ZINTSA EQU 4 ;SERIAL A ZINTSB EQU 5 ;SERIAL B ZINTKD EQU 6 ;KEYBOARD OR DISPLAY ZINTPP EQU 7 ;PARALLEL PRINTER ; SLAVE 8259A ZINTST EQU 0C8H ;BASE TRAP VECTOR # ; INTERRUPT EXIT TRAP VECTOR #'S ZINTXM EQU 0D0H ;EXIT FOR MASTER 8259A ZINTXS EQU 0D1H ;EXIT FOR SLAVE 8259A ZINTXSW EQU 0D2H ;EXIT FOR SOFTWARE INTERRUPTS  [ ;** Z-MACHINE KEYBOARD DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; PORT ASSIGNMENTS ZKEYBDD EQU ZKEYBD+0 ;DATA ZKEYBDC EQU ZKEYBD+1 ;COMMAND ZKEYBDS EQU ZKEYBD+1 ;STATUS ; STATUS REGISTER ZKEYOBF EQU 0% 1B ;OUTPUT BUFFER FULL ZKEYIBF EQU 0;10B ;INPUT BUFFER FULL ; COMMANDS ZKEYRES EQU 000H ;RESET ZKEYARO EQU 001H ;AUTOREPEAT ON ZKEYARF EQU 002H ;AUTOREPEAT OFF ZKEYKCO EQU 003H ;KEY CLICK ON ZKEYKCF EQU 004H ;KEY CLICK OFF ZKEYCF EQU 005H ;CLEAR FIFO ZKEYCLK EQU 006H ;CLICK ZKEYBEP EQU 007H ;BEEP ZKEYEK EQU 008H ;ENABLE KEYBOARD ZKEYDK EQU 009H ;DISABLE KEYBOARD ZKEYUDM EQU 00AH ;KEY UP/DOWN MODE ZKEYNSM EQU 00BH ;NORMAL SCAN MODE ZKEYEI EQU 00CH ;ENABLE INTERRUPTS ZKEYDI EQU 00DH ;DISABLE INTERRUPTS ; SPECIAL KEYS ZKEYBRK EQU 0AAH ;BREAK KEY  e ;** Z-MACHINE MEMORY MAP UTILIZATION EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; ,"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST BOOTORG EQU 0400H ;BOOT CODE LOAD ADDRESS BCODEL EQU 256+64 ;MAXIMUM BOOT CODE LENGTH LDCPMOS EQU 48*1024 ;WHERE CP/M LOADER IS LOADED LDCCP EQU 0000H ; OFFSET OF CCP LDBDOS EQU 0406H ; OFFSET OF BDOS LDBIOS EQU 1200H ; OFFSET OF BIOS LDBIOSL EQU 52*128-LDBIOS-BCODEL ; MAXIMUM LOADER BIOS SIZE CPMOS EQU 0400H ;WHERE CP/M SYSTEM IS LOADED CPMCCP EQU 0000H ; OFFSET OF CCP CPMBDOS EQU 0B06H ; OFFSET OF BDOS CPMBIOS EQU 2500H ; OFFSET OF BIOS  b ;** Z-MACHINE MONITOR ROM MTR-100 EQUATES ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;* MONITOR ENTRY POINTS ; ; THESE VECTORS ARE PROVIDED AS ALTERNATE ENTRY POINTS ; INTO THE MONITOR ROUTINES. ; MTRSEG EQU 0FE01H ;SEGMENT VALUE ; OFFSET VALUES MTRRES EQU 0nH ;RESET THE MONITOR MTRMON EQU 00005H ;MONITOR ENTRY MTRSWIM EQU 0000AH ;SOFTWARE INTERRUPT MTRDCRT EQU 0000FH ;DUMB CRT PROCESSOR MTRDKBD EQU 00014H ;DUMP KEYBOARD PROCESSOR MTRSCRT EQU 00019H ;SMART CRT PROCESSOR MTRSKBD EQU 0001EH ;SMART KEYBOARD PROCESSOR MTRTINT EQU 00023H ;TERMINAL INTERRUPT HANDLER (VERTICAL SYNC) MTRIRET EQU 00028H ;INTERRUPT RETURN ;* MONITOR DATA AREA MTRDSEG EQU 03FEH ;OFFSET IN PAGE ZERO OF POINTER TO BE USED ; AS THE DATA SEGMENT VALUE ; DATA AREA DEFINITIONS ORG 0 RB 5 ;WILD INTERRUPT JMPF INSTRUCTION MTRVER RB 1 ;VERSION MTRDSZ RW 1 ;DATA AREA SIZE IN BYTES ; BOOT PARAMETERS MTRBI RB 1 ;BOOT DEVICE INDEX MTRBP RB 1 ;BOOT DEVICE BASE PORT MTRBS RB 80 ;BOOT STRING MTRBU RB 1 ;BOOT UNIT ; RAM VECTORS FOR PARAMETERIZED ROUTINES MTRDCI RW 2 ;DISPLAY CHARACTER INITIALIZATION MTRDFC RW 2 ;DISPLAY FONT CHARACTER MTRDXMTC RW 2 ;DUMB KEYBOARD TRANSMIT CHARACTER MTREDC RW 2 ;ERASE DISPLAY CHARACTER MTREMEC RW 2 ;EXTENDED-MODE ESCAPE CHARACTER MTRFONT RW 2 ;CHARACTER FONT ADDRESS MTRMDC RW 2 ;MOVE DISPLAY CHARACTER MTRMDL RW 2 ;MOVE DISPLAY LINE MTRP RW 2 ;DISPLAY MONITOR PROMPT MTRRDC RW 2 ;READ DISPLAYED CHARACTER MTRSXMTC RW 2 ;SMART KEYBOARD TRANSMIT CHARACTER MTRUIES RW 2 ;UNIMPLEMENTED ESCAPE SEQUENCE MTRXCA RW 2 ;TRANSMIT CHARACTER ATTRIBUTES ; CHAR ACTER FONT VALUES MTRFNTL RW 1 ;CHARACTER FONT TABLE LENGTH IN BYTES MTRKMAP RB 256 ;KEYBOARD MAP MTRDMAP RB 256 ;DISPLAY MAP  W ;** Z-MACHINE PORT ASSIGNMENTS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; a"Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ZVIDEO EQU 0D8H ;VIDEO 68A21 ZCRTC EQU 0DCH ;VIDEO 6845 CRTC ZLPEN EQU 0DEH ;LIGHT PEN COUNTER ZGDP EQU 0E0H ;GENERAL DATA PORT (68A21) ZTIMER EQU 0E4H ;8253 TIMER ZSERA EQU 0E8H ;SERIAL A ZSERB EQU 0ECH ;SERIAL B Z8259AS EQU 0F0H ;8259A SLAVE Z8259AM EQU 0F2H ;8259A MASTER ZKEYBD EQU 0F4H ;KEYBOARD ZTSTAT EQU 0FBH ;TIMER STATUS ZMCL EQU 0FCH ;MEMORY CONTROL LATCH ZHAL EQU 0FDH ;HI-ADDRESS LATCH ZPSP EQU 0FEH ;PROCESSOR SWAP PORT ZDIPSW EQU 0FFH ;DIP SWITCHES ; MEMORY CONTROL LATCH ZMCLMS EQU 011B ;MAP SELECT MASK ZMS0 EQU 000H ; MAP SELECT 0 ZMS1 EQU 001H ; MAP SELECT 1 ZMS2 EQU 002H ; MAP SELECT 2 ZMS3 EQU 003H ; MAP SELECT 3 ZMCLRM EQU 00001100B ;MONITOR ROM MAPPING ZRM0 EQU 000H ; POWER UP MODE - ROM EVERYWHERE ON READS ZRM1 EQU 004H ; ROM AT THE TOP 8K OF EVERY 64K ZRM2 EQU 008H ; ROM AT THE TOP 8K OF THE 8088'S ADDR SPACE ZRM3 EQU 00CH ; DISABLE ROM ZMCLP EQU 00110000B ;PARITY HANDLING ZMCLPZ EQU 00010000B ; 0=SET PARITY TO THE ZERO STATE ZMCLPK EQU 0010L B ; 0=DISABLE PARITY CHECKING CIRCUITRY ; HI-ADDRESS LATCH ZHAL85 EQU 1V B ;8085 MASK ZHAL88 EQU 00001111B ;8088 MASK ; PROCESSOR SWAP PORT ZPSPPS EQU 10u B ;PROCESSOR SELECT (0=8085 , 1=8088) ZPSPPS5 EQU 000H ; SELECT 8085 ZPSPPS8 EQU 080H ; SELECT 8088 ZPSPGIS EQU 01 10B ;GENERATE INTERRUPT ON SWAPPING ZPSPI88 EQU 0' 1B ;8088 PROCESSES ALL INTERRUPTS Y ;** Z100 VIDEO BOARD DEFINITIONS ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; - ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ; 6821 USE ; ; PA0 -> ENABLE RED DISPLAY ; PA1 -> ENABLE GREEN DISPLAY ; PA2 -> ENABLE BLUE DISPLAY ; PA3 -> NOT FLASH SCREEN ; PA4 -> NOT WRITE MULTIPLE RED ; PA5 -> NOT WRITE MULTIPLE GREEN ; PA6 -> NOT WRITE MULTIPLE BLUE ; PA7 -> DISABLE VIDEO RAM ; PB0-PB7 -> LA15-LA8 ; CA1 - NOT USED ; CA2 -> CLEAR SCREEN ; CB1 - NOT USED ; CB2 -> VALUE TO WRITE (0 OR 1) ON CLEAR SCREEN ; LIGHT PEN LATCH ZLPENBIT EQU 0 111B ;BIT HIT BY PEN ZLPENROW EQU 11110000B ;ROW HIT BY PEN ; LIGHT PEN VALUES ZLPENEV EQU 5 ;LIGHT PEN ERROR VALUE