;B2BIOS56.ASM 29 MAR 81 RHP ;56K VERISON FOR BASE 2 PRINTER ; ; CP/M BASIC INPUT/OUTPUT OPERATING SYSTEM (BIOS) ; TARBELL ELECTRONICS ; 2.2 VERSION OF 2-19-80 ; CHANGED SIGN-ON FOR CPM 2.2 2-19-80 ; ; THIS MODULE CONTAINS ALL THE INPUT/OUTPUT ; ROUTINES FOR THE CP/M SYSTEM, INCLUDING ; THE DISK ROUTINES. ; ; THIS SECTION DEFINES THE I/O PORTS AND ; STATUS BITS. BY SETTING THE PROPER VALUES ; FOR THE EQU STATEMENTS, THE I/O MAY BE ; AUTOMATICALLY RECONFIGURED TO FIT MOST ; SITUATIONS. THE TRUE AND FALSE ONES ; CONTROL CONDITIONAL ASSEMBLIES OF DIFFERENT ; SECTIONS OF I/O ROUTINES TO FIT DIFFERENT ; INTERFACE REQUIREMENTS. FFFF = TRUE EQU 0FFFFH ;DEFINE VALUE OF TRUE. 0000 = FALSE EQU NOT TRUE ;DEFINE VALUE OF FALSE. ;*************************************************** ;*** THIS BEGINS THE AREA WHICH REQUIRES CHANGES *** ;*** FOR DIFFERENT CONSOLE I/O SYSTEMS *** ;*************************************************** 0038 = MSIZE EQU 56 ;MEMORY SIZE IN KBYTES. 0000 = INTRP EQU FALSE ;TRUE IF INTERRUPTS ALLOWED. 0000 = STD EQU FALSE ;TRUE IF STANDARD I/O. 0000 = MSIO2 EQU FALSE ;TRUE IF MITS 2SIO. 0000 = DELTA EQU FALSE ;TRUE IF USING DELTA PRODUCTS CPU. 0000 = ISIO2 EQU FALSE ;TRUE IF IMSAI SIO-2. 0000 = TUART EQU FALSE ;TRUE IF CROMEMCO TUART. FFFF = VIDEO EQU TRUE ;TRUE IF USING A MEMORY MAPPED VIDEO. FFFF = OTHER EQU TRUE ;TRUE IF SOMETHING ELSE. 0000 = SOLOS EQU FALSE ;TRUE IF PROC TECH SOLOS. 0000 = DUBSID EQU FALSE ;TRUE FOR DOUBLE SIDED DRIVES. 0000 = SPOOL EQU FALSE ;TRUE IF USING KLH SPOOLER. 0002 = NDISK EQU 2 ;DEFINES THE NUMBER DRIVES IN SYSTEM. IF VIDEO ;IF USING A VIDEO BOARD F803 = OUTADDR EQU 0F803H ;PUT OUTPUT ADDRESS HERE ENDIF IF NOT SOLOS ;IF NOT PROC TECH SOLOS, 0003 = CSTAT EQU 3 ;CONSOLE STATUS PORT. ENDIF 0003 = CCOM EQU 3 ;CONSOLE COMMAND PORT. 0002 = CDATA EQU 2 ;CONSOLE DATA PORT. 0000 = CONUL EQU FALSE ;CONSOLE NULLS? 0000 = CNULL EQU 0 ;CONSOLE NULL COUNT. 000A = LSTAT EQU 0AH ;NLIST STATUS PORT. 000A = LCOM EQU 0AH ;LIST COMMAND PORT. 000B = LDATA EQU 0BH ;LIST DATA PORT. 0000 = LSTNUL EQU FALSE ;LIST DEVICE NULLS? 0000 = LNULL EQU 0 ;LIST NULL COUNT. 0000 = LSTPAG EQU FALSE ;LIST DEVICE PAGING? 0042 = LINCNT EQU 66 ;LINES PER PAGE. 0000 = HLAB EQU 0 ;8 FOR HD LD AT BEG OF SEEK. 0001 = STPRAT EQU 1 ;RATE 1=6MS, 2=10MS, 3=20MS. 0000 = DUAL EQU FALSE ;TRUE IF DUAL DRIVE. FFFF = PERSCI EQU TRUE ;TRUE IF FAST SEEK (PERSCI). ;******************************************************* ;*** THIS IS THE END OF THE AREA WHICH NORMALLY NEED *** ;*** BE CHANGED FOR MOST CONSOLE I/O SYSTEMS *** ;******************************************************* 0000 = RDYLO EQU STD OR SOLOS ;STATUS READY WHEN LOW. FFFF = RDYHI EQU NOT RDYLO IF SOLOS ;IF PROC TECH SOLOS, CSTAT EQU 0FAH ;CONSOLE STATUS PORT. KBD EQU 0C02EH ;SOLOS KEYBOARD. CLRSCR EQU 0C0D5H ;CLEAR SCREEN. SCRN EQU 0C054H ;SOLOS OUTPUT. ENDIF IF NOT SOLOS ;IF NOT PROC TECH SOLOS, 00F8 = DISK EQU 0F8H ;DISK BASE ADDRESS. ENDIF IF SOLOS ;IF PROC TECH SOLOS, DISK EQU 0E8H ;DIFFERENT DISK PORTS. ENDIF 00F8 = DCOM EQU DISK ;DISK COMMAND PORT. 00F8 = DSTAT EQU DISK ;DISK STATUS PORT. 00F9 = TRACK EQU DISK+1 ;DISK TRACK PORT. 00FA = SECTP EQU DISK+2 ;DISK SECTOR PORT. 00FB = DDATA EQU DISK+3 ;DISK DATA PORT. 00FC = WAIT EQU DISK+4 ;DISK WAIT PORT. 00FC = DCONT EQU DISK+4 ;DISK CONTROL PORT. 000A = RTCNT EQU 10 ;RETRY COUNT. IF STD ;IF STANDARD I/O, CKBR EQU 00000001B ;KEYBOARD READY BIT. CPTR EQU 10000000B ;CONS OUTPUT RDY BIT. ENDIF IF MSIO2 ;IF MITS 2SIO, CKBR EQU 00000001B ;KEYBOARD READY BIT. CPTR EQU 00000010B ;PRINT READY BIT. ENDIF IF ISIO2 OR DELTA CKBR EQU 00000010B ;KEYBOARD READY BIT. CPTR EQU 00000001B ;PRINT READY BIT. ENDIF IF TUART ;IF CROMEMCO TUART, CKBR EQU 01000000B ;KEYBOARD READY BIT. CPTR EQU 10000000B ;PRINT READY BIT. ENDIF IF SOLOS ;IF PROC TECH SOLOS, CKBR EQU 00000001B ;KEYBOARD READY BIT. CPTR EQU 10000000B ;DUMMY EQU. ENDIF IF OTHER ;IF SOMETHING ELSE, 0002 = CKBR EQU 00000010B ;KEYBOARD READY BIT. 0080 = CPTR EQU 10000000B ;PRINTER READY BIT. ENDIF 0080 = LRBIT EQU CPTR ;LISTER READY BIT. 0003 = IOBYTE EQU 3 ;ADDRESS OF I/O BYTE. 9000 = CBASE EQU (MSIZE-20)*1024 ;BIAS FOR LARGER THAN 20K. C400 = CPMB EQU CBASE+3400H ;START OF CPM 2.0 CC06 = BDOS EQU CPMB+806H ;START OF BDOS 2.0. DA00 = BIOS EQU CPMB+1600H ;START OF CBIOS IO. 0004 = CDISK EQU 4 ;LOCATION 4 IS CURRENT DISK. 002C = NSECTS EQU 44 ;NUMBER OF SECTORS IN IT. DA00 ORG BIOS ;START OF CBIOS STRUCTURE. ; ; I/O JUMP VECTOR ; THIS IS WHERE CPM CALLS WHENEVER IT NEEDS ; TO DO ANY INPUT/OUTPUT OPERATION. ; USER PROGRAMS MAY USE THESE ENTRY POINTS ; ALSO, BUT NOTE THAT THE LOCATION OF THIS ; VECTOR CHANGES WITH THE MEMORY SIZE. ; DA00 C39CDA JMP BOOT ;FROM COLD START LOADER. DA03 C3E6DA WBOOTE: JMP WBOOT ;FROM WARM BOOT. DA06 C33FDB JMP CONST ;CHECK CONSOLE KB STATUS. DA09 C348DB JMP CONIN ;READ CONSOLE CHARACTER. DA0C C354DB JMP CONOT ;WRITE CONSOLE CHARACTER. DA0F C31CDD JMP LIST ;WRITE LISTING CHAR. DA12 C32EDD JMP PUNCH ;WRITE PUNCH CHAR. DA15 C32FDD JMP READER ;READ READER CHAR. DA18 C394DB JMP HOME ;MOVE DISK TO TRACK ZERO. DA1B C359DB JMP SELDSK ;SELECT DISK DRIVE. DA1E C396DB JMP SETTRK ;SEEK TO TRACK IN REG A. DA21 C3FFDB JMP SETSEC ;SET SECTOR NUMBER. DA24 C30ADC JMP SETDMA ;SET DISK STARTING ADR. DA27 C331DC JMP READ ;READ SELECTED SECTOR. DA2A C3B5DC JMP WRITE ;WRITE SELECTED SECTOR. DA2D C319DD JMP PRSTAT ;LIST STATUS CHECK. DA30 C304DC JMP SECTRAN ;SECTOR TRANSLATE ROUTINE. ; THESE ENTRY POINTS ADDED BY TARBELL ELECTRONICS. IF SPOOL ;IF USING KLH SPOOLER. DB 0FFH ;FLAG FOR SPOOLER. DW LTBSY ;LISTER STATUS LOCATION DW LTBSY ;FOR SPOOLER - - DW LTBSY ;I DON'T KNOW WHY IT'S DW LTBSY ;HERE 4 TIMES EITHER. ENDIF ; ; THIS SECTION DEFINES THE THE DISK PARAMETERS ; NOTE: ; IF YOU HAVE THE MACRO ASSEMBLER (MAC) FROM ; DIGITAL RESEARCH, YOU MAY ELIMINATE THIS SECTION ; STARTING AT **AA** TO **BB** AND USE THE MACRO ; FILE "DISKDEF" TO CUSTOM TAILOR YOUR SYSTEM TO ; ALLOW DIFFERENT TYPES OF DRIVES OR MORE THAN 4 ; DRIVES. ; ;**AA** ; DA33 = DPBASE EQU $ ;BASE OF DISK PARAMETER BLOCK DA33 82DA0000 DPE0: DW XLT0,0000H ;TRANSLATE TABLE DA37 00000000 DW 0000H,0000H ;SCRATCH AREA DA3B 42DD73DA DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK DA3F E1DDC2DD DW CSV0,ALV0 ;CHECK, ALLOC VECTORS ; DA43 82DA0000 DPE1: DW XLT1,0000H DA47 00000000 DW 0000H,0000H DA4B 42DD73DA DW DIRBUF,DPB1 DA4F 10DEF1DD DW CSV1,ALV1 ; DA53 82DA0000 DPE2: DW XLT2,0000H DA57 00000000 DW 0000H,0000H DA5B 42DD73DA DW DIRBUF,DPB2 DA5F 3FDE20DE DW CSV2,ALV2 ; DA63 82DA0000 DPE3: DW XLT3,0000H DA67 00000000 DW 0000H,0000H DA6B 42DD73DA DW DIRBUF,DPB3 DA6F 6EDE4FDE DW CSV3,ALV3 ; ;THE FOLLOWING DESCRIBES THE DISK PHYSICAL ;NATURE, SUCH AS SECTORS/TRACK,DIRECTORY SIZE. ; DA73 = DPB0 EQU $ ;ONE OF 4 DISK PARM. BLOCKS DA73 1A00 DW 26 ;SECTORS/TRACK DA75 03 DB 3 ;BLOCK SHIFT DA76 07 DB 7 ;BLOCK MASK DA77 00 DB 0 ;EXTNT MASK DA78 F200 DW 242 ;DISK SIZE - 1 DA7A 3F00 DW 63 ;DIRECTORY MAX. DA7C C0 DB 192 ;ALLOC0 DA7D 00 DB 0 ;ALLOC1 DA7E 1000 DW 16 ;CHECK SIZE DA80 0200 DW 2 ;NUMBER OF SYSTEM TRACKS ; ;SECTOR TRANSLATION TABLE ; DA82 = XLT0 EQU $ ;START OF TRANS. TABLE DA82 01070D1319 DB 1,7,13,19,25 DA87 050B111703 DB 5,11,17,23,3 DA8C 090F150208 DB 9,15,21,2,8 DA91 0E141A060C DB 14,20,26,6,12 DA96 1218040A10 DB 18,24,4,10,16,22 ; DA73 = DPB1 EQU DPB0 ;EQUIVALENT PARAMETERS DA82 = XLT1 EQU XLT0 ;SAME TRANSLATE TABLE ; DA73 = DPB2 EQU DPB0 DA82 = XLT2 EQU XLT0 ; DA73 = DPB3 EQU DPB0 DA82 = XLT3 EQU XLT0 ; ;**BB** ; ; ; BOOT ; THIS SECTION IS EXECUTED WHENEVER RESET AND RUN ; IS PUSHED, AFTER THE COLDSTART LOADER READS IN ; THE CPM SYSTEM. ; DA9C 318000 BOOT: LXI SP,80H ;SET STACK POINTER. IF INTRP ;IF INTERRUPTS ALLOWED, EI ;ENABLE THEM HERE. ENDIF DA9F CD00F8 CALL 0F800H ;INITIALIZE VIDEO BOARD. IF STD ;IF STANDARD I/O, DW 0,0 ;LEAVE SPACE FOR INIT. DW 0,0 DW 0,0 DW 0,0 ENDIF IF MSIO2 ;IF MITS 2SIO, MVI A,3 ;INITIALIZE 2SIO. OUT CCOM OUT LCOM MVI A,11H OUT CCOM OUT LCOM ENDIF IF ISIO2 OR DELTA MVI A,0AAH ;INITIALIZE SIO 2-2. OUT CCOM OUT LCOM MVI A,40H OUT CCOM OUT LCOM MVI A,0CEH OUT CCOM OUT LCOM MVI A,37H OUT CCOM OUT LCOM ENDIF IF TUART ;IF CROMEMCO TUART, MVI A,1 ;SET A = 1. OUT 54H ;SELECT DEVICE A. OUT 52H ;RESET DEVICE B. LXI H,BAUDRS ;GET ADR OF BAUD RATE TABLE. MVI A,11H ;OCTUPLE THE CLOCK. IT1: OUT 02H ;& RESET CURRENT DEV. MOV A,M ;GET BAUD RATE FROM TABLE. INX H ;INCREMENT POINTER. OUT 0 ;SET BAUD RATE. CALL CONIN ;READ KEYBOARD. CALL CONIN ;READ KEYBOARD AGAIN. CPI 0DH ;IF NOT CARRIAGE-RETURN, MVI A,1 ;SLOW THE CLOCK. JNZ IT1 ;UNTIL A CARRIAGE-RETURN. ENDIF IF SOLOS ;IF PROC TECH SOLOS, CALL CLRSCR ;CLEAR SCREEN. ENDIF DAA2 AF XRA A ;CLEAR SCRATCH AREA. DAA3 320300 STA IOBYTE ;CLEAR I/O BYTE. DAA6 320400 STA CDISK ;SELECT DRIVE ZERO DAA9 0E09 MVI C,ENDZ-STARTZ ;GET LENGTH OF ZERO AREA. DAAB 2134DD LXI H,STARTZ ;GET SCRATCH ADDRESS. DAAE 77 BOOTL: MOV M,A ;PUT ZERO IN MEMORY. DAAF 23 INX H ;INCREMENT POINTER. DAB0 0D DCR C ;DECREMENT COUNTER. DAB1 C2AEDA JNZ BOOTL ;LOOP TILL DONE. DAB4 3EF2 MVI A,0F2H ;SET LATCH CODE = F2. DAB6 3240DD STA LATCH DAB9 CDCBDA CALL SETUP ;SET UP JUMPS. DABC DB02 IN CDATA ;CLEAR CONSOLE STATUS. DABE 21F2DC LXI H,SMSG ;PRINT OPENING MESSAGE. DAC1 CDE0DC CALL PMSG DAC4 3A0400 GOCPM: LDA CDISK ;GET DISK NUMBER TO DAC7 4F MOV C,A ;PASS TO CCP IN C. DAC8 C300C4 JMP CPMB ;JUMP TO CCP. ; ; SET UP JUMPS INTO CP/M IN LOWER MEMORY. ; DACB 3EC3 SETUP: MVI A,0C3H ;PUT JMP TO WBOOT DACD 320000 STA 0 ;ADR AT ZERO. DAD0 2103DA LXI H,WBOOTE DAD3 220100 SHLD 1 DAD6 320500 STA 5 DAD9 2106CC LXI H,BDOS ;PUT JUMP TO BDOS DADC 220600 SHLD 6 ;AT ADR 5,6,7. DADF 218000 LXI H,80H ;SET DEFAULT DMA ADR. DAE2 2232DD SHLD DMAADD DAE5 C9 RET ;RETURN FROM SETUP. IF TUART ;IF CROMEMCO TUART, BAUDRS: DB 94H,0CEH,0A2H,92H,88H,84H,82H,1 ENDIF ; ; WARM-BOOT: READ ALL OF CPM BACK IN ; EXCEPT BIOS, THEN JUMP TO CCP. ; DAE6 318000 WBOOT: LXI SP,80H ;SET STACK POINTER. IF INTRP ;IF INTERRUPTS ALLOWED, EI ;ALLOW THEM HERE. ENDIF IF LSTPAG ;IF LIST DEVICE PAGING, XRA A ;RESET LINE-FEED COUNT. STA LFCNT ENDIF DAE9 3A0400 LDA CDISK ;SAVE DISK NUMBER. DAEC 323FDD STA TEMP DAEF 0E00 MVI C,0 ;SELECT DISK ZERO. DAF1 CD59DB CALL SELDSK DAF4 CD94DB CALL HOME ;MOVE TO TRACK ZERO. DAF7 C234DB JNZ RDERR ;IF ERROR, PRINT MESSAGE. DAFA 162C MVI D,NSECTS ;GET # SECTORS FOR CPM READ. DAFC 010200 LXI B,2 ;TRACK (B)=0, SECTOR (C)=2. DAFF 2100C4 LXI H,CPMB ;GET STARTING ADDRESS. IF INTRP ;IF INTERRUPTS ALLOWED, DI ;DISABLE THEM HERE. ENDIF DB02 C5 RDBLK: PUSH B ;SAVE B&C. DB03 48 MOV C,B ;GO TO TRACK IN B. DB04 CD96DB CALL SETTRK DB07 C1 POP B ;RESTORE B&C. DB08 C234DB JNZ RDERR ;IF ERROR, PRINT MESSAGE. DB0B 2232DD RBLK1: SHLD DMAADD ;SET STARTING ADDRESS. DB0E CDFFDB CALL SETSEC ;READ STARTING AT SECTOR IN C. DB11 CD31DC CALL READ DB14 C234DB JNZ RDERR ;IF ERROR, PRINT MESSAGE. DB17 15 DCR D ;DECREMENT SECTOR COUNT. DB18 CA28DB JZ ALDON ;ALL DONE WHEN D=0. DB1B 0C INR C ;INCREMENT SECTOR NUMBER. DB1C 79 MOV A,C ;IF SECTOR NUMBER DB1D FE1B CPI 27 ;IS NOT 27, DB1F DA0BDB JC RBLK1 ;KEEP READING ON THIS TRACK. DB22 0E01 MVI C,1 ;OTHERWISE, RESET SECTOR=1, DB24 04 INR B ;INCREMENT TRACK NUMBER, DB25 C302DB JMP RDBLK ;AND READ NEXT TRACK. DB28 3A3FDD ALDON: LDA TEMP ;RESTORE DISK NUMBER. IF INTRP ;IF INTERRUPTS ALLOWED, EI ;ALLOW THEM AGAIN HERE. ENDIF DB2B 320400 STA CDISK DB2E CDCBDA CALL SETUP ;SET UP JUMPS. DB31 C3C4DA JMP GOCPM ;GO BACK TO CPM. ; DB34 0E42 RDERR: MVI C,'B' ;GET BOOT ERROR CODE. DB36 CD54DB CALL CONOT ;PRINT IT. DB39 CD48DB CALL CONIN ;READ A CHAR FROM CONSOLE. DB3C C3E6DA JMP WBOOT ;DO A WARM BOOT. ; ; CHECK CONSOLE INPUT STATUS. ; DB3F DB03 CONST: IN CSTAT ;READ CONSOLE STATUS. DB41 E602 ANI CKBR ;LOOK AT KB READY BIT. DB43 3E00 CONST1: MVI A,0 ;SET A=0 FOR RETURN. IF RDYLO ;IF STATUS READY LOW, RNZ ;NOT READY WHEN NOT 0. ENDIF IF RDYHI ;IF STATUS READY HIGH, DB45 C8 RZ ;NOT READY WHEN ZERO. ENDIF DB46 2F CMA ;IF READY A=FF. DB47 C9 RET ;RETURN FROM CONST. ; ; READ A CHARACTER FROM CONSOLE. ; CONIN: IF NOT SOLOS ;IF NOT PROC TECH SOLOS, DB48 DB03 IN CSTAT ;READ CONSOLE STATUS. DB4A E602 ANI CKBR ;IF NOT READY, ENDIF IF SOLOS ;IF PROC TECH SOLOS, CALL KBD ;READ SOL KEYBOARD. JZ CONIN ;READY WHEN NOT ZERO. ENDIF IF RDYLO AND NOT SOLOS JNZ CONIN ;LOOP UNTIL LOW. ENDIF IF RDYHI ;IF READY WHEN HIGH, DB4C CA48DB JZ CONIN ;LOOP UNTIL HIGH. ENDIF IF NOT SOLOS ;IF NOT PROC TECH SOLOS, DB4F DB02 IN CDATA ;READ A CHARACTER. ENDIF DB51 E67F ANI 7FH ;MAKE MOST SIG. BIT = 0. DB53 C9 RET ;RETURN FROM CONIN. ; ; WRITE A CHARACTER TO THE CONSOLE DEVICE. ; CONOT: IF CONUL ;IF NULLS REQUIRED, MVI A,0DH ;IF IT'S A CR, CMP C ;THEN HOP OUT JZ CONULL ;TO NULL ROUTINE. ENDIF CONOT1: IF NOT SOLOS AND NOT VIDEO IN CSTAT ;READ CONSOLE STATUS. ANI CPTR ;IF NOT READY, ENDIF IF RDYLO AND NOT SOLOS AND NOT VIDEO JNZ CONOT1 ;LOOP UNTIL LOW. ENDIF IF RDYHI AND NOT VIDEO ;IF READY WHEN HIGH, JZ CONOT1 ;LOOP UNTIL HIGH. ENDIF IF NOT SOLOS AND NOT VIDEO MOV A,C ;GET CHARACTER. OUT CDATA ;PRINT IT. RET ;RETURN. ENDIF ; ;THIS ROUTINE CALLES YOUR VIDEO DRIVER ;ROUTINE WHICH MUST BE IN ROM. ;ALL REGISTERS MUST BE SAVED AND RESTORED ;BY YOUR VIDEO DRIVER IN ORDER TO BE ;COMPATIABLE WITH CPM. ;CPM PASSES THE CHAR. TO BE OUTPUT IN THE ; C REGISTER. MAKE ANY CHANGES IN THIS ;ROUTINE TO PASS THE CHAR FROM REG C TO ;THE REGISTER YOUR VIDEO DRIVER EXPECTS ;IT TO BE IN. ; IF VIDEO ;IF USING A VIDEO DRIVER IN ROM. DB54 79 MOV A,C ;GET THE CPM CHAR INTO REG A DB55 CD03F8 CALL OUTADDR ;CALL YOUR VIDEO DRIVER. DB58 C9 RET ;RETURN TO CPM. ENDIF IF CONUL CONULL: PUSH B ;SAVE B&C. MVI B,CNULL+1 ;GET NULL COUNT. CONUL1: CALL CONOT1 ;PRINT CR. MVI C,0 ;GET NULL CHAR. DCR B ;DECREMENT COUNTER. JNZ CONUL1 ;DO NEXT NULL. POP B ;RESTORE B&C. MOV A,C ;RESTORE A. RET ;RETURN. ENDIF IF SOLOS ;IF PROC TECH SOLOS, PUSH B ;SAVE B&C. MOV B,C ;PUT CHAR IN B REG. CALL SCRN ;OUTPUT CHAR TO SOLOS. POP B ;RESTORE B&C. MOV A,C ;PUT CHAR IN A. RET ;RETURN FROM CONOT. ENDIF ; ; SELECT DISK NUMBER ACCORDING TO REGISTER C. ; SELDSK: DB59 210000 LXI H,0 ;SET UP FOR ERROR CODE DB5C 79 MOV A,C ;GET NEW DRIVE. DB5D FE02 CPI NDISK ;CALLING UNDEFINED DRIVE ? DB5F D0 RNC ;IF NO CY, H,L TELLS CPM YES. DB60 3235DD STA PDISK ;WE ARE OK, SAVE NEW DISK NUMB. DB63 2134DD LXI H,DISKNO ;GET OLD DRIVE NUMBER. SELMOR: DB66 7E MOV A,M ;GET OLD DISK NUMBER. IF DUAL ;IF DUAL DRIVE, ANI 0FEH ;CLEAR OUT BIT 0. ENDIF DB67 5F MOV E,A ;PUT OLD DISK NO. IN D&E. DB68 1600 MVI D,0 DB6A 2139DD LXI H,TRTAB ;GET ADDRESS OF TRACK TABLE. DB6D E5 PUSH H ;SAVE ADDRESS OF TRTAB. DB6E 19 DAD D ;ADD DISK NO. TO ADDRESS. DB6F DBF9 IN TRACK ;READ 1771 TRACK REGISTER. DB71 77 MOV M,A ;PUT INTO TABLE. DB72 79 MOV A,C ;GET NEW DISK NUMBER. IF DUAL ;IF A DUAL DRIVE, ANI 0FEH ;CLEAR BIT 0. ENDIF DB73 5F MOV E,A ;PUT NEW DISK NO. IN D&E. DB74 E1 POP H ;RESTORE ADDRESS OF TRTAB. DB75 19 DAD D ;ADD DISK NO. TO ADDRESS. DB76 7E MOV A,M ;GET NEW TRACK NUMBER. DB77 D3F9 OUT TRACK ;PUT INTO 1771 TRACK REG. DB79 79 MOV A,C ;UPDATE OLD DISK NUMBER. DB7A 3234DD STA DISKNO DB7D 2F CMA ;BITS INVERTED INTO LATCH. DB7E 87 ADD A ;PUT BITS 1&2 AT 4&5. DB7F 87 ADD A DB80 87 ADD A DB81 87 ADD A DB82 F602 ORI 2 ;MAKE LATCH COMMAND. DB84 3240DD STA LATCH ;SAVE NEW LATCH CODE. ; ;SELECT DRIVE AS A FUNCTION OF H,L ; DB87 2A35DD LHLD PDISK ;LOAD DISK NUMBER AND ZERO BYTE DB8A 1133DA LXI D,DPBASE ;POINT TO DISK PARM START. DB8D 29 DAD H ;*2 DB8E 29 DAD H ; *4 DB8F 29 DAD H ; *8 DB90 29 DAD H ; *16 DB91 19 DAD D ;COMPUTE INDEX FOR THE DRIVE DB92 AF XRA A ;SET A = 0. DB93 C9 RET ;RETURN FROM SELDSK. ; ; MOVE DISK TO TRACK ZERO. ; DB94 0E00 HOME: MVI C,0 ;SEEK TO TRACK ZERO. ; ; SET TRACK NUMBER TO WHATEVER IS IN REGISTER C. ; ALSO PERFORM MOVE TO THE CORRECT TRACK (SEEK). ; SETTRK: IF NOT DUBSID ;IF NOT DOUBLE-SIDED, DB96 E5 PUSH H ;SAVE H&L. DB97 2A40DD LHLD LATCH ;GET NEW & OLD LATCH. DB9A 7D MOV A,L ;GET NEW LATCH. DB9B D3FC OUT DCONT ;SELECT DRIVE NOW. DB9D 3241DD STA CLATCH ;REMEMBER CURRENT LATCH. DBA0 BC CMP H ;IS NEW SAME AS OLD? DBA1 3EFF MVI A,0FFH ;IF NOT, SET FLAG = FF. DBA3 C2A7DB JNZ SFLAG DBA6 2F CMA ;IF NEW = OLD, FLAG = 0. DBA7 3237DD SFLAG: STA HLSF ;SET HEAD-LOAD/SELECT FLAG. DBAA E1 POP H ;RESTORE H&L. ENDIF DBAB 79 MOV A,C ;GET NEW TRACK NUMBER. IF DUBSID ;IF DOUBLE-SIDED DISK, RRC ;SHIFT RIGHT ONCE. PUSH PSW ;SAVE REVISED TRACK NUMBER. PUSH H ;SAVE H&L. LHLD LATCH ;GET NEW & OLD LATCH. MOV A,L ;PUT NEW LATCH IN A. JC SIDE2 ;IF TRACK # ODD, SIDE #2. ORI 40H ;CLEAR LATCH BIT FOR SIDE 1. JMP SETLAT ;GO AHEAD AND SET LATCH. SIDE2: ANI 0B2H ;SET LATCH BIT FOR SIDE 2. SETLAT: OUT DCONT ;OUTPUT TO THE LATCH. STA CLATCH ;SET CURRENT LATCH CODE. XRA H ;COMPARE OLD WITH NEW, ANI 0BFH ;IGNORE SIDE BIT. MVI A,0FFH ;IF OLD NOT = NEW, JNZ SETFL ; SET FLAG = FF. CMA A ;IF OLD = NEW, FLAG = 0. SETFL: STA HLSF ;SET FLAG ZERO IF SAME. POP H ;RESTORE H&L. POP PSW ;RESTORE THE TRACK NUMBER. ANI 7FH ;CLEAR MSB. MOV C,A ;SET C=TRACK NUMBER. ENDIF DBAC 3230DD STA TRK ;UPDATE OLD WITH NEW. ; ; MOVE THE HEAD TO THE TRACK IN REGISTER A. ; DBAF C5 SEEK: PUSH B ;SAVE B&C. DBB0 47 MOV B,A ;SAVE DESTINATION TRACK. DBB1 3E0A MVI A,RTCNT ;GET RETRY COUNT. DBB3 323EDD SRETRY: STA SERCNT ;STORE IN ERROR COUNTER. DBB6 DBF9 IN TRACK ;READ PRESENT TRACK NO. DBB8 4F MOV C,A ;SOME DBB9 79 MOV A,C ; DELAY DBBA B8 CMP B ;SAME AS NEW TRACK NO.? DBBB C2C0DB JNZ NOTHR ;JUMP IF NOT THERE. DBBE C1 THERE: POP B ;RESTORE B&C. DBBF C9 RET ;RETURN FROM SEEK. NOTHR: ; ;THIS ROUTINE IS TO ALLOW TIME FOR THE DRIVE ;TUNNEL ERASE TO TERMINATE BEFORE MOVING THE ;HEAD. THE DELAY IS APPROX. 700 MICRO-SEC. @ ;4 MHZ CPU TIME, AND DOUBLE THIS FOR 2 MHZ CPU'S. ; DBC0 F5 PUSH PSW ;SAVE ACCUM DBC1 3ED0 MVI A,0D0H ;DELAY COUNT = 208 DBC3 3D BUSY1: DCR A ;DECREASE COUNT DBC4 C2C3DB JNZ BUSY1 ;LOOP TILL DONE DBC7 F1 POP PSW ;RESTORE ACCUM IF NOT PERSCI ;IF NOT PERSCI DRIVE, MOV A,B ;RESTORE A FROM B. OUT DDATA ;TRACK TO DATA REGISTER. BUSY: IN DSTAT ;READ DISK STATUS. RRC ;LOOK AT BIT 0. JC BUSY ;WAIT TILL NOT BUSY. MVI A,14H+STPRAT+HLAB ;GET STEP RATE, DO OUT DCOM ;SEEK WITH VERIFY. IN WAIT ;WAIT FOR INTRQ. IN DSTAT ;READ STATUS. ANI 91H ;LOOK AT BITS. JZ THERE ;OK IF ZERO. ENDIF IF PERSCI ;IF PERSCI DRIVE, DBC8 3E40 MVI A,40H+HLAB ;IF CARRY = 1, DBCA DACFDB JC SDIR ;STEP IN. DBCD 3E60 MVI A,60H+HLAB ;OTHERWISE, OUT. DBCF D3F8 SDIR: OUT DCOM ;ISSUE STEP DIRECTION. DBD1 3E14 MVI A,20 ;DELAY LOOP COUNT. DBD3 3D DLOOP: DCR A ;DECREMENT COUNTER. DBD4 C2D3DB JNZ DLOOP DBD7 79 MOV A,C ;GET PRESENT TRACK. DBD8 90 SUB B ;FIGURE TRACKS TO STEP. DBD9 F2DEDB JP STEP ;IF NEGATIVE, DBDC 2F CMA ;FIGURE THE DBDD 3C INR A ;TWO'S COMPLEMENT. DBDE 4F STEP: MOV C,A ;GET DIFFERENCE. DBDF 3E01 MVI A,1 ;PERSCI STEP COMMAND. DBE1 D3FC STEP1: OUT DCONT ;STEP PERSCI (E-14). DBE3 0D DCR C ;COUNT THE STEP. DBE4 C2E1DB JNZ STEP1 ;STEP UNTIL C = 0. DBE7 DBFC IN WAIT ;CLEAR 1771. DBE9 DBF8 IN DSTAT DBEB 78 MOV A,B ;GET DEST. TRACK. DBEC D3F9 OUT TRACK ;UPDATE TRACK REG. DBEE 3A41DD LDA CLATCH ;GET LATCH CODE. DBF1 E672 ANI 72H ;MAKE COMMAND TO DBF3 D3FC OUT DCONT ;SWITCH WAIT FOR DBF5 DBFC IN WAIT ;SEEK COMPLETE. DBF7 3A41DD LDA CLATCH ;RESTORE LATCH TO DBFA D3FC OUT DCONT ;OLD CODE. DBFC AF XRA A ;MAKE GOOD RETURN. DBFD C1 POP B ;RESTORE B&C. DBFE C9 RET ENDIF IF NOT PERSCI ;IF NOT PERSCI DRIVE, LDA SERCNT ;GET ERROR COUNT. DCR A ;DECREMENT COUNT. JNZ SRETRY ;RETRY SEEK. POP B ;RESTORE B&C. CALL RECOV ;IF SEEK RETRY = 10 CHECK JMP SEEK ; FOR CNTL-C FOR ABORT. ENDIF ; ; SET DISK SECTOR NUMBER. ; DBFF 79 SETSEC: MOV A,C ;GET SECTOR NUMBER. DC00 3231DD STA SECT ;PUT AT SECT # ADDRESS. DC03 C9 RET ;RETURN FROM SETSEC. ; ;TRANSLATE THE SECTOR GIVEN B,C ;USING THE TRANSLATE TABLE ;GIVEN BY D,E ; SECTRAN: DC04 EB XCHG ;H,L = TRANS DC05 09 DAD B ;H,L = TRANS (SECTOR) DC06 6E MOV L,M ;L = TRANS (SECTOR) DC07 2600 MVI H,0 ;CLEAR REG H DC09 C9 RET ;H,L = TRANSLATED SECTOR ; ; SET DISK DMA ADDRESS. ; DC0A 60 SETDMA: MOV H,B ;MOVE B&C TO H&L. DC0B 69 MOV L,C DC0C 2232DD SHLD DMAADD ;PUT AT DMA ADR ADDRESS. DC0F C9 RET ;RETURN FROM SETDMA. ; ; HDLD - GET HEAD-LOAD BIT IF REQUIRED. ; DC10 3A37DD HDLD: LDA HLSF ;GET HEAD-LOAD FLAG. DC13 B7 ORA A ;IS A = ZERO? DC14 CA28DC JZ HDLD1 ;HOP IF SO. DC17 2F CMA ;SET A = 0. DC18 3237DD STA HLSF ;SET FLAG = 0 IF NOT. ; ;IF CHANGING TO A NEW DRIVE, PERFORM A SEEK TO ;THE SAME TRACK TO ALLOW THE HEAD TO UNLOAD. ; DC1B DBF9 IN TRACK ;GET PRESENT TRACK DC1D D3FB OUT DDATA ;AND TELL 1771 ABOUT IT. DC1F 3E15 MVI A,14H+STPRAT+HLAB ;GET THE STEP RATE. DC21 D3F8 OUT DCOM ;SEND IT TO FLOPPY CONTROLLER. DC23 DBFC IN WAIT ;WAIT FOR INTRQ. DC25 3E04 HDLDY: MVI A,4 ;SET BIT TO LOAD HEAD. DC27 C9 RET ;RETURN FROM HDLD. DC28 DBF8 HDLD1: IN DSTAT ;READ 1771 STATUS. DC2A E620 ANI 20H ;LOOK AT HL BIT. DC2C CA25DC JZ HDLDY ;LOAD IF NOT LOADED. DC2F AF XRA A ;OTHERWISE, A=0. DC30 C9 RET ;RETURN FROM HDLD. ; ; READ THE SECTOR AT SECT, FROM THE PRESENT TRACK. ; USE STARTING ADDRESS AT DMAADD. ; DC31 3E0A READ: MVI A,RTCNT ;GET RETRY COUNT. RRETRY: DC33 CDA0DC CALL DSKSET ;SET UP DISK. DC36 C688 ADI 88H ;ADD CODE FOR READ SECT. DC38 D3F8 READE: OUT DCOM ;SEND COMMAND TO 1771. DC3A DBFC RLOOP: IN WAIT ;WAIT FOR DRQ OR INTRQ. DC3C B7 ORA A ;SET FLAGS. DC3D F247DC JP RDDONE ;DONE IF INTRQ. DC40 DBFB IN DDATA ;READ A DATA BYTE FROM DISK. DC42 77 MOV M,A ;PUT BYTE INTO MEMORY. DC43 23 INX H ;INCREMENT MEMORY POINTER. DC44 C33ADC JMP RLOOP ;KEEP READING. DC47 DBF8 RDDONE: IN DSTAT ;READ DISK STATUS. IF INTRP ;IF INTERRUPTS ALLOWED, EI ;ALLOW AGAIN HERE. ENDIF DC49 E69D ANI 9DH ;LOOK AT ERROR BITS. DC4B C8 RZ ;RETURN IF NONE. DC4C CD6BDC CALL ERCHK ;CHECK FOR SEEK ERROR. DC4F 3A3DDD LDA ERCNT ;GET ERROR COUNT. DC52 3D DCR A ;DECREMENT COUNT. DC53 C233DC JNZ RRETRY ;TRY TO READ AGAIN. DC56 CD5CDC CALL RECOV ;CHECK FOR ABORT OR CONTINUE DC59 C331DC JMP READ ;IF NOT CNTL-C, TRY TO READ AGAIN. ; ;RECOV ;THIS ROUTINE IS CALLED BY ANY READ,WRITE,SEEK ;ROUTINE IF THE RETRY COUNT GOES TO 10. IF IT ;DOES,THIS ROUTINE CALLS CONIN FOR A KEY TO BE ;PUSHED. IF THE KEY IS A CNTL-C, THEN A WARMBOOT ;IS EXECUTED. IF ANY OTHER KEY IS PUSHED, THEN ;A RETURN IS MADE BACK TO THE CALLER AND THAT ;ROUTINE IS RETRIED FOR 10 MORE TIMES. ; DC5C 21EBDC RECOV: LXI H,ERRMSG ;POINT TO "ERROR" MESSAGE. DC5F CDE0DC CALL PMSG ;PRINT IT ON CONSOL. DC62 CD48DB CALL CONIN ;CHECK FOR PUSHED KEY. DC65 FE03 CPI 03H ;IS IT A CNTL-C ? DC67 C0 RNZ ;RETURN TO CALLER IF NOT. DC68 C3E6DA JMP WBOOT ;YES, DO WARMBOOT. ; ; ERCHK - CHECK FOR RECORD NOT FOUND ERROR. ; DC6B 57 ERCHK: MOV D,A ;SAVE ERROR BITS IN D. DC6C E610 ANI 10H ;IF RECORD NOT FOUND, DC6E C274DC JNZ CHKSK ;DO A CHECK ON SEEK. DC71 7A MOV A,D ;OTHERWISE RESTORE BITS DC72 B7 ORA A ;SET FLAGS, DC73 C9 RET ;AND RETURN. ;CHECK FOR SEEK TO CORRECT TRACK, ;AND CHANGE IF NECESSARY. DC74 3EC4 CHKSK: MVI A,0C4H ;SEND COMMAND TO 1771 DC76 D3F8 OUT DCOM ;TO READ ADDRESS. DC78 DBFC IN WAIT ;WAIT FOR DRQ OR INTRQ. DC7A DBFB IN DDATA ;READ THE TRACK ADDRESS. DC7C 47 MOV B,A ;SAVE IN REGISTER B. DC7D DBFC CHKS2: IN WAIT ;WAIT FOR INTRQ. DC7F B7 ORA A ;SET FLAGS. DC80 F288DC JP CHKS3 ;DONE WITH READ ADR OP. DC83 DBFB IN DDATA ;READ ANOTHER BYTE. DC85 C37DDC JMP CHKS2 ;DO IT AGAIN. DC88 DBF8 CHKS3: IN DSTAT ;READ DISK STATUS. DC8A B7 ORA A ;SET FLAGS. DC8B CA94DC JZ CHKS4 ;READ ADR OK IF 0. DC8E CD94DB CALL HOME ;OTHERWISE, HOME FIRST. DC91 C397DC JMP CHKS5 DC94 78 CHKS4: MOV A,B ;UPDATE TRACK REGISTER. DC95 D3F9 OUT TRACK DC97 3A30DD CHKS5: LDA TRK ;GET REQUIRED TRACK NO. DC9A CDAFDB CALL SEEK ;MOVE THE HEAD TO IT. DC9D 7A MOV A,D ;GET ERROR BITS. DC9E B7 ORA A ;SET FLAGS. DC9F C9 RET ;RETURN FROM ERCHK. ; ;DISK SET UP ROUTINE. ;THIS ROUTINE IS COMMON TO ;BOTH THE READ AND WRITE ;ROUTINES. ; DSKSET: DCA0 323DDD STA ERCNT ;STORE IN ERROR CTR. DCA3 3ED0 MVI A,0D0H ;CAUSE INTERRUPT. DCA5 D3F8 OUT DCOM DCA7 E3 XTHL ;SOME DCA8 E3 XTHL ; DELAY IF INTRP ;IF INTERRUPTS ALLOWED, DI ;DISABLE THEM HERE. ENDIF DCA9 2A32DD LHLD DMAADD ;GET STARTING ADDR. DCAC 3A31DD LDA SECT ;GET SECTOR NUMBER. DCAF D3FA OUT SECTP ;SET SECTOR INTO 1771. DCB1 CD10DC CALL HDLD ;GET HEAD-LOAD BIT? DCB4 C9 RET ;RETURN TO CALLER ; ; WRITE THE SECTOR AT SECT, ON THE PRESENT TRACK. ; USE STARTING ADDRESS AT DMAADD. ; DCB5 3E0A WRITE: MVI A,RTCNT ;GET RETRY COUNT. WRETRY: DCB7 CDA0DC CALL DSKSET ;SET UP DISK. DCBA C6A8 ADI 0A8H ;ADD CODE FOR WRITE. DCBC D3F8 WRITE2: OUT DCOM DCBE DBFC WLOOP: IN WAIT ;WAIT FOR READY. DCC0 B7 ORA A ;SET FLAGS. DCC1 F2CBDC JP WDONE ;HOP OUT WHEN DONE. DCC4 7E MOV A,M ;GET BYTE FROM MEM. DCC5 D3FB OUT DDATA ;WRITE ONTO DISK. DCC7 23 INX H ;INCREMENT MEM PTR. DCC8 C3BEDC JMP WLOOP ;KEEP WRITING. DCCB DBF8 WDONE: IN DSTAT ;READ DISK STATUS. IF INTRP ;IF INTERRUPTS ALLOWED, EI ;ENABLE AGAIN HERE. ENDIF DCCD E6FD ANI 0FDH ;LOOK AT THESE BITS. DCCF C8 RZ ;RETURN IF NO ERR. DCD0 CD6BDC CALL ERCHK ;CHECK/CORRECT SEEK ERR. DCD3 3A3DDD LDA ERCNT ;GET ERROR COUNT. DCD6 3D DCR A ;DECREMENT COUNT. DCD7 C2B7DC JNZ WRETRY ;TRY TO WRITE AGAIN. DCDA CD5CDC CALL RECOV ;CHECK FOR ABORT DCDD C3B5DC JMP WRITE ;RETRY WRITE AGAIN. ; ; PRINT THE MESSAGE AT H&L UNTIL A ZERO. ; DCE0 7E PMSG: MOV A,M ;GET A CHARACTER. DCE1 B7 ORA A ;IF IT'S ZERO, DCE2 C8 RZ ;RETURN. DCE3 4F MOV C,A ;OTHERWISE, DCE4 CD54DB CALL CONOT ;PRINT IT. DCE7 23 INX H ;INCREMENT H&L, DCE8 C3E0DC JMP PMSG ;AND GET ANOTHER. ; ; CBIOS MESSAGES ; DCEB 4552524F52ERRMSG: DB 'ERROR.',0 DCF2 0D0A546172SMSG: DB 0DH,0AH,'Tarbell ' DCFC 3536 DB MSIZE/10+'0',MSIZE MOD 10 + '0' DCFE 4B2043504D DB 'K CPM 2.2',0DH,0AH DD09 4241534520 DB 'BASE 2 PRINTER ',0 ; ;LIST STATUS CHECK ROUTINE ; PRSTAT: DD19 3EFF MVI A,0FFH ;DUMMY PRINTER READY DD1B C9 RET ; ; WRITE A CHARACTER ON LISTING DEVICE. ; LIST: IF LSTNUL ;IF NULLS OR PAGING, MVI A,0DH ;IF IT'S A CR, CMP C ;THEN HOP OUT TO JZ LINUL ;NULL ROUTINE. ENDIF IF LSTPAG ;IF PAGING MVI A,0AH ;GET A LINEFEED CMP C ;DOES IT MATCH? JZ LINUL3 ENDIF LTBSY: ;LISTER STATUS NOT USED DD1C DB0A IN 0AH ;READ STATUS DD1E E602 ANI 02 ;CHECK BUSY,0=READY,1=BUSY DD20 C21CDD JNZ LTBSY ;LOOP TIL FREE DD23 DB0A IN 0AH ;READ STATUS AGAIN DD25 E680 ANI 80H ;CHECK TBE,0=BUSY,1=READY DD27 CA1CDD JZ LTBSY ;LOOP TIL LAST CHAR SENT DD2A 79 MOV A,C ;GET CHAR TO SEND DD2B D30B OUT 0BH ;SEND IT DD2D C9 RET ;BACK FOR ANOTHER IF LSTNUL ;IF LIST NULLS LINUL: PUSH B ;SAVE B&C. MVI B,(LNULL AND 0FFH)+1 ;GET NULL COUNT LINUL1: CALL LTBSY ;PRINT (CR FIRST). MVI C,0 ;GET NULL CHAR. DCR B ;DECREMENT COUNTER. JNZ LINUL1 ;DO NEXT NULL. JMP LINUL2 ;EXIT THE ROUTINE. ENDIF IF LSTPAG ;IF LIST DEV. PAGING, LINUL3: PUSH B ;SAVE B,C PAIR LDA LFCNT ;GET LINE-FEED COUNT. INR A ;INCREMENT IT. STA LFCNT ;SAVE IT BACK. CPI LINCNT-(LINCNT/11) ;END OF PAGE? MVI B,1 ;SET UP FOR 1 LF. JNZ NOTEOP ;HOP IF NOT END. XRA A ;SET LF COUNT = 0. STA LFCNT MVI B,(LINCNT/11)+1 ;BETWEEN PAGES. NOTEOP: MVI C,0AH ;GET LINE-FEED CODE. LSTPA1: CALL LTBSY ;PRINT LINE-FEED. DCR B ;DECREMENT LF COUNTER. JNZ LSTPA1 ;DO NEXT LINE FEED? ENDIF IF LSTNUL OR LSTPAG ;IF NULLS OR PAGING, LINUL2: POP B ;RESTORE B&C. MOV A,C ;RESTORE A. RET ;RETURN FROM LIST. ENDIF ; ; PUNCH PAPER TAPE. ; PUNCH: DD2E C9 RET ;RETURN FROM PUNCH. ; ; NORMALLY USED TO READ PAPER TAPE. ; READER: DD2F C9 RET ;RETURN FROM READER. ;NOTE: AS THERE ARE ONLY SIX (6) SECTORS ;AVAILABLE FOR CBIOS ON THE SECOND SYSTEM TRACK (1), ;THE LAST ADDRESS BEFORE THIS POINT SHOULD BE NO ;GREATER THAN THE CBIOS STARTING ADDRESS + 037F (HEX). ;THIS WILL NORMALLY BE XD7F (HEX). ; ; BIOS SCRATCH AREA. ; DD30 TRK: DS 1 ;CURRENT TRACK NUMBER. DD31 SECT: DS 1 ;CURRENT SECTOR NUMBER. DD32 DMAADD: DS 2 ;DISK TRANSFER ADDRESS. ; ; THE NEXT SEVERAL BYTES, BETWEEN STARTZ AND ; ENDZ, ARE SET TO ZERO AT COLD BOOT TIME. ; STARTZ: ;START OF ZEROED AREA. DD34 DISKNO: DS 1 ;DISK NUMBER DD35 PDISK: DS 2 ;NEW DISK TO SELECT AND A ZERO BYTE ; SPECIAL FLAGS. DD37 HLSF: DS 1 ;HEAD-LOAD SELECT FLAG. DD38 LFCNT: DS 1 ;PAGING LINE-FEED COUNT. ; ; TRTAB - DISK TRACK TABLE - PRESENT POSITION OF ; HEADS FOR UP TO 4 DRIVES. ; DD39 TRTAB: DS 4 ENDZ: ;END OF ZEROED AREA. DD3D ERCNT: DS 1 ;ERROR COUNT FOR RETRIES. DD3E SERCNT: DS 1 ;SEEK RETRY COUNTER. DD3F TEMP: DS 1 ;TEMPORARY STORAGE. DD40 LATCH: DS 1 ;NEW CODE FOR LATCH. DD41 CLATCH: DS 1 ;CURRENT CODE IN LATCH. DD42 = BEGDAT EQU $ DD42 DIRBUF: DS 128 ;DIRECTORY BUFFER DDC2 ALV0: DS 31 DDE1 CSV0: DS 16 DDF1 ALV1: DS 31 DE10 CSV1: DS 16 DE20 ALV2: DS 31 DE3F CSV2: DS 16 DE4F ALV3: DS 31 DE6E CSV3: DS 16 DE7E = ENDDAT EQU $ 013C = DATSIZ EQU $-BEGDAT ;TOTAL SIZE OF DISK PARM STORAGE. DE7E END