|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 30464 (0x7700)
Types: TextFile
Names: »MPFBIOS.ASM«
└─⟦60a2a8c28⟧ Bits:30004392 CP/M-80 rel. 2 sources
└─⟦this⟧ »MPFBIOS.ASM«
TITLE 'DUAL FLOPPY BIOS FOR TANDOM TM 100 DRIVES. DATE: 820715'
PAGE 43
;***************************************************************************
; CHRISTIAN ROVSING A/S CP/M MINI DISK BIOS FOR TANDON
; TM 100 96 TPI O IS HANDLED VIA THE ON BOARD Z80 SIO
; USART CHIPS AND A 8253 COUNTER TIMER/CHIP THAT IS PROGRAMMED
; TO PROVIDE THE BAUD RATE CLOCK. FLOPPY DISK I/O IS OBTAINED
; THE ONBOARD 1793 FLOPPY DISK CONTROLLER. THE TWO SUPPORTED MINI
; FLOPPY DISK DRIVES A THE MP2 BOARD BOARD.
; THIS BIOS CONFIGURATION WILL SUPPORT
; ONE AND OPTIONALLY TWO MINI FLOPPY DRIVES. MINI FLOPPY FORMAT
; IS AS FOLLOWS:
;
; 77 TRACKS
; 16 RECORDS PER TRACK
; TWO HEADS/SIDES
; 256 BYTE RECORDS
; CP/M MAPS LOGICAL DRIVCONTROLLER ARE USED. REAL
; ACCESS TO THE SECTOR PAIRS IS AS FOLLOWS:
;
; 1,2; 5,6; 9,10; 13,14; 3,4; 7,8; 11,12; 15,16;
;
PAGE
;
; MAPPING OF THE MINI FLOPPY ALLOWS THE FIRST TWO TRACKS TO BE
; SYSTEM TRACKS. THE FIRST SECTOR OF THE FIRSMINI FLOPPY DISK DRIVES
;***************************************************************************
;
;
; THIS CP/M BIOS IS SETUP FOR VERSION 2.2 CP/M ON A CHRISTIAN
; ROVSING A/S MP2 BOARD WITH Z80 PROCESSOR AND 64K OF RAM.
; CONSOLE AND PRINTER I/RE MOUNTED IN THE FRONT PANEL OF THE CR8
; WORKSTATION COMPUTER UNIT.
;
; THIS BIOS CONTAINS MINIFLOPPY DISK DRIVERS TO SUPPORT 5 1/4 INCH
; MINIFLOPPY DISKS. ACCESS AND CONTROL OF THE MINI FLOPPY WILL
; BE THROUGH THE DISK CONTROLLER CIRCUITRY OFE E: TO THE MINI FLOPPY WITH
; ODD TRACKS ON HEAD 0 AND EVEN TRACKS ON HEAD 1.
;
; BIOS ACCESS TO THE MINI FLOPPY IS DONE IN REAL PAIRS OF 256 BYTE
; SECTORS TO AND FROM THE 512 BYTE HOST BUFFER. MULTIPLE SECTOR
; READ AND WRITE COMMANDS OF THE 1793 T TRACK
; CONTAINS SPECIAL LOAD INFORMATION UTILIZED BY THE LOADER TO
; COLD BOOT THE CP/M IMAGE FROM THE FLOPPY SYSTEM TRACKS. THE BOOT
; TIME INFORMATION AVAILABLE INCLUDES THE BASE ADDRESS OF THE CCP,
; THE LENGTH OF THE CP/M (CCP+BIOS) IMAGE TO LOAD, THE COLD START
; CONSOLE BAUD RATE AND THE COLD START LINE PRINTER BAUD RATE. PSUEDO
; SECTOR SIZE ON THE FLOPPY DISK IS 512 BYTES SO THIS BIOS DOES
; DEBLOCKING DOWN TO THE 128 BYTE SECTOR SIZE DESIRED BY THE CP/M
; FILE MANAGER. THIS MINI FLOPPYGRAM RUNS UNDER ANY CP/M AND TALKS DIRECTLY
; TO BASIC I/O SUBROUTINES. GETPUT LOAD ADDRESSES ARE SHOWN BELOW:
;
;
; BASE ADDRESS OF CCP =0D800H
; BASE ADDRESS OF BIOS=0EE00H
; TRACK 0 SECTOR 1 AT GETPUTF = 03480H
; CCP AT GETPUT POSITION =AGE
;
;DEFINE TRUE AND FALSE ASSEMBLY PARAMETERS
;
TRUE EQU -1 ;DEFINE TRUE
FALSE EQU NOT TRUE ;DEFINE FALSE
;
;
;
;CP/M VERSION 2.2 SYSTEM PARAMETERS
;
MSIZE EQU 61 ;MEMORY SIZE IN DECIMAL KILO-BYTES
BIAS EQU (MSIZE-20)*1024 ;BIAS FOR LARGER;
;VERSION NUMBER AND DATE
;
VERSION EQU 22 ;VERSION NUMBER
MONTH EQU 07 ;MONTH
DAY EQU 15 ;DAY
YEAR EQU 82 ;YEAR LAST TWO DIGITS
;
;
;CP/M SYSTEM BASE ADDRESS, STACK ADDRESS, DEFAULT DMA ADDRESS
;
BASE EQU 000H ;CP/M SYSTEM BASE ADDRESS
I SYSTEM TRACK LAYOUT IS DESIGNED TO
; BE COMPATIBLE WITH THE CHRISTIAN ROVSING A/S VERSION OF A HARD DISK
; BIOS.
;
; THE FOLLOWING INFORMATION IS USEFUL IN "SYSGENING" CP/M 2.2 ONTO
; FLOPPY DISK. THE APPROPIATE PROGRAM TO USE IS GETPUTF.
; THIS PRO 03680H
; BIOS AT GETPUT POSITION = 04C80H
; OFFSET TO READ MP2DFBS.HEX
; ...INTO GETPUTF POSITION = 05E80H
;
;
; THIS BIOS WAS MADE BY: LARS WINTER.
;*****************************************************************************
;
P THAN 20K
OFFSET EQU 0D580H-BIAS ;OFFSET VALUE FOR SYSGEN POSITION 1F80H
CCP EQU BIAS+3400H ;START OF CCP 2.2
BDOS EQU CCP+806H ;START OF BDOS 2.2
CPML EQU 1600H ;LENGTH OF CP/M SYSTEM MINUS BIOS
NSECTS EQU CPML/512 ;NUMBER OF SECTORS IN IT
;
OBYTE EQU 003H ;ADDRESS OF I/O BYTE
STACK EQU 080H ;LOCAL STACK POINTER ADDRESS
DFDMA EQU 080H ;DEFAULT DMA ADDRESS
LOGDSK EQU 004H ;CP/M'S ADDRESS OF CURRENTLY LOGGED
;...DISK
;
;
DELBS EQU FALSE ;SET TRUE IF CONIN ROUTINE TO CONVERT
;DELETE CHAR TO BACKSPACE
;
PAGE
;
;DEFINE MEMORY BASED I/O MODULE ENTRY POINTS
;
MODBASE EQU 0F800H ;SET JUMP TABLE EQUIVALENT ADDRESSES
;
INITSER EQU MODBASE+00 ;INITIALIZE HARDWARE I/O PORTS
; ;(NO PARAMETERS)
SETCBAUD EQU MODBASE+03 ;SE PRINTER SIO MASK BYTE
SETLRVAL EQU MODBASE+012 ;SET LINE PRINTER SIO RECEIVER POLL VALUE
; ;(A) = LINE PRINTER POLL VALUE
SETLTMSK EQU MODBASE+015 ;SET LINE PRINTER SIO TRANSMITTER MASK VALUE
; ;(A) = LINE PRINTER SIO MASK BYTE
SETLTVAL EQU MODINPUT CHARACTER
; ;(A)=INPUT CONSOLE CHARACTER
CONOUT EQU MODBASE+027 ;PUT OUT CONSOLE CHAR
; ;(C)=CHARACTER TO OUTPUT
LPTSTAT EQU MODBASE+030 ;GET LINE PRINTER STATUS
; ;RETURN (A)=00 FOR NOT NEXT OUTPUT
; ; (A)=FF FOR READY OUTPUT
LPTI=UNIT NUMBER ON MSC 9205 CONTROLLER
HPLAT EQU MODBASE+042 ;SELECT HARD DISK PLATTER (HEAD) NUMBER
; ;(C)=HEAD SELECT NUMBER
HSURF EQU MODBASE+045 ;SELECT HARD DISK SURFACE(HEAD 2^2) NUMBER
; ;(C)=MSB OF HEAD NUMBER
HCYL EQU MODBASE+048 ;SELECT T CONSOLE I/O BAUD RATE FACTOR
; ;(HL) = COUNTER TIMER PARAMETER VALUE
SETLBAUD EQU MODBASE+06 ;SET LINE PRINTER I/O BAUD RATE FACTOR
; ;(HL) = COUNTER TIMER VALUE
SETLRMSK EQU MODBASE+09 ;SET LINE PRINTER SIO RECEIVER MASK VALUE
;(A) = LINEBASE+018 ;SET LINE PRINTER SIO TRANSMITTER POLL VALUE
; ;(A) = LINE PRINTER SIO POLL VALUE BYTE
CONSTAT EQU MODBASE+021 ;GET CONSOLE STATUS
; ;RETURN (A)=00 FOR NOT READY INPUT
; ; (A)=FF FOR READY INPUT
CONIN EQU MODBASE+024 ;GO GET CONSOLE N EQU MODBASE+033 ;GO GET LINE PRINTER INPUT CHARACTER
; ;(A)=INPUT LPT SERIAL PORT CHARACTER
LPTOUT EQU MODBASE+036 ;PUT OUT LINE PRINTER CHARACTER
; ;(C)=LPT SERIAL OUTPUT CHARACTER
HUNIT EQU MODBASE+039 ;SELECT HARD DISK UNIT NUMBER
; ;(C)HARD DISK CYLINDER NUMBER
; ;(BC)=CYLINDER NUMBER
HREC EQU MODBASE+051 ;SELECT HARD DISK RECORD NUMBER
; ;(C)=RECORD NUMBER
HCNT EQU MODBASE+054 ;SELECT HARD DISK SECTOR COUNT
; ;(C)=RECORD COUNT
HBADDR EQU MODBASE+057 ;SET 9205 CONTROLLER DMA ADDRESS
; ;(BC)=16 BIT DATA BUFFER ADDRESS
HREST EQU MODBASE+060 ;RESTORE SELECTED HARD DISK UNIT
; ;(A) RETURNS ERROR CODE
HREAD EQU MODBASE+063 ;READ SELECTED SECTOR(S)
; ;(A) RETURNS ERROR CODE
HVERF EQU MODBASE+066 ;VERIFY SELECTED SEQU MODBASE+075 ;RESET HARD DISK CONTROLLER MSC 9205
; ;NO PARAMETERS
MUNIT EQU MODBASE+078 ;SELECT MINI FLOPPY UNIT NUMBER
; ;(C)=FLOPPY PHYSICAL UNIT NUMBER
MSURF EQU MODBASE+081 ;SELECT MINI FLOPPY SURFACE(HEAD) NUMBER
; ;(C)=FLOPPY SIDE NU ;(C)=MINI FLOPPY SECTOR COUNT
MSSIZE EQU MODBASE+093 ;SELECT FLOPPY SECTOR SIZE (00)=256 BYTES
; ;(C)=MINI FLOPPY TRACK NUMBER
MBADDR EQU MODBASE+096 ;SET FLOPPY DISK DATA BUFFER ADDRESS
; ;(BC)=FLOPPY BUFFER ADDRESS
MREST EQU MODBASE+099 ;REECTOR
; ;(A)=RETURNED STARUS
MWTRK EQU MODBASE+111 ;WRITE SELECTED FLOPPY TRACK
; ;(A)=RETURNED STATUS
MMODE EQU MODBASE+114 ;SET FLOPPY OPERATION MODE
; ;(C)=STANDARD MODE DEFINITION
MINST EQU MODBASE+117 ;FETCH CURRENT INSTRUCTION CODE
; CTOR(S)
; ;(A) RETURNS ERROR CODE
HWRIT EQU MODBASE+069 ;WRITE SELECTED SECTOR(S);
; ;(A) RETURNS ERROR CODE
HEXEC EQU MODBASE+072 ;EXECUTE SPECIAL COMMAND OF MSC 9205
; ;(C) ENTRY WITH MSC 9205 COMMAND
; ;(A) RETURNS ERROR CODE
HRESET EMBER
MCYL EQU MODBASE+084 ;SELECT MINI FLOPPY CYLINDER(TRACK) NUMBER
; ;(C)=FLOPPY TRACK NUMBER
MREC EQU MODBASE+087 ;SELECT MINI FLOPPY RECORD NUMBER
; ;(C)=FLOPPY SECTOR NUMBER
MCNT EQU MODBASE+090 ;SELECT MINI FLOPPY PHYSICAL SECTOR COUNT
; STORE SELECTED MINI FLOPPY UNIT
; ;(A)=RETURNS ERROR STATUS
MVERF EQU MODBASE+102 ;VERIFY (READ) SELECTED SECTOR
; ;(A)=RETURNS STATUS
MWRIT EQU MODBASE+105 ;WRITE SELECTED SECTOR
; ;(A)=RETURNED STATUS
MREAD EQU MODBASE+108 ;READ SELECTED S ;(A)=RETURNED INSTRUCTION PATTERN
MMOFF EQU MODBASE+120 ;CHECK MINI FLOPPY MOTOR ON COUNT
; ;OUT TIMER
;
;ASCII CHARACTER DEFINITIONS
;
BS EQU 008H ;ASCII BACK SPACE CHARACTER
LF EQU 00AH ;ASCII LINE FEED CHARACTER
CR EQU 00DH ;ASCII CARRIAGE RETURN CHARACTER
ESC EQU 01BH ;ASCII ESCAPE CHARACTER
RUBOUT EQU 07FH ;ASCII RUBOUT CHARACTER
;
;
;MP2 BOARD UNIT/MODE REGISTER FOR DISK CHARACTERISTICS SELECT
;
; BIT 7 - COMPENSATION "1" ENABLES FLOPPY WRITE PRECOMPENSATION
; BIT 6 - DRI ;MINI DRIVE ENABLE
DENSEL EQU 020H ;BIT MASK FOR DENSITY SELECT
;
;
;DEFINE MP2 BOARD RAM CONTROL PORT ADDRESS
;
RAMCTL EQU 0AH
;
PAGE
;
;CP/M BIOS DISK CONFIGURATION SELECTION OPTIONS
;
DEFDSK EQU 00H ;DEFAULT BOOTED DISK
; 00=A:
OG2(HBLK), RETURN @X AS RESULT
; (2 ** @X = HBLK ON RETURN)
;
@Y SET HBLK
@X SET 0
;
; COUNT RIGHT SHIFTS OF @Y UNTIL = 1
;
REPT 8
IF @Y = 1
EXITM
ENDIF
;
; @Y IS NOT 1, SHIFT RIGHT ONE POSITION
;
@Y SET @Y SHR 1
@X SET @X + 1
ENDM
/M 2.2 TO HOST DISK CONSTANTS
;
BLKSIZ EQU 2048 ;CP/M ALLOCATION SIZE
HSTSIZ EQU 512 ;HOST DISK SECTOR SIZE
;
FDSPT EQU 8 ;HOST MINI FLOPPY DISK 256 BYTE SECTOR PAIRS
;PER TRACK
HSTBLK EQU HSTSIZ/128 ;CP/M SECTS/HOST BUFF
;
;CPMSPT EQU HSTBVE TYPE "1" SELECTS CLOCKING FOR A 5 1/4 DRIVE
; "0" SELECTS FOR AN 8 INCH UNIT
; BIT 5 - DENSITY "1" SETS FOR MFM DOUBLE DENSITY
; "0" SELECTS FM SINGLE DENSITY
;
COMPEN EQU 080H ;WRITE COMPENSATION ENABLE
MINIEN EQU 040H ; 01=B:
; ***
; *** NOTE THAT ONLY MINI FLOPPY MAY
; *** BE BOOTED VIA THIS BIOS
; ***
;
;
;SECTOR DEBLOCKING ALGORITHMS FOR CP/M 2.2
;
MACLIB DISKDEF
;
SMASK MACRO HBLK ;UTILITY MACRO TO COMPUTE SECTOR MASK
;
; COMPUTE LENDM
;
PAGE
;MACRO DEFINITIONS FOR Z-80 BLOCK MOVE INSTRUCTIONS REQUIRED FOR DISK
;DATA INTERFACE ON THE MP2 BOARD BOARD
;
OUTIR MACRO
DB 0EDH,0B3H ;Z80 OUTPUT BLOCK MOVE
ENDM
;
INIR MACRO
DB 0EDH,0B2H ;Z80 INPUT BLOCK MOVE
ENDM
;
;
;CPLK * HSTSPT ;CP/M SECTORS/TRACK
; ;THIS VALUE CHANGES ACCORDING TO
; ;MINI OR HARD DISK.
;
SECMSK EQU HSTBLK-1 ;SECTOR MASK
SMASK HSTBLK ;COMPUTE SECTOR MASK
SECSHF EQU @X ;LOG2(HSTBLK)
;
;SECTOR SKEW INTERLACE FACTOR
;
SKEW EQU 00 ;SECTOR SKEW FACTOR
;
;BDOS CONSTANTS ON ENTRY TO "WRITE"
;
WRALL EQU 0 ;WRITE TO ALLOCATED BLOCK
WRDIR EQU 1 ;WRITE TO DIRECTORY
WRUAL EQU 2 ;WRITE TO UNALLOCATED BLOCK
;
PAGE
;
ORG CCP+1600H ;START OF BIOS
;
;
;
;I/O JUMP VECTOR
;THIS ISBOOT ;FROM WARM BOOT
JMP CSTS ;CHECK CONSOLE KB STATUS
JMP CI ;READ CONSOLE CHARACTER
JMP CO ;WRITE CONSOLE CHARACTER
JMP LPTOUT ;WRITE LISTING CHAR
JMP PUNCH ;WRITE PUNCH CHAR
JMP READER ;READ READER CHAR
JMP HOME ;MOVE DISK T
JMP SECTRAN ;SECTOR TRANSLATE
;
;
;ADDITIONAL JUMPS INSTALLED BY CHRISTIAN ROVSING A/S FOR SPECIAL ENHANCEMENTS
;TO THE HARD DISK CP/M SYSTEM SOFTWARE
;
JMP CBCPMIN ;PROM/FLOPPY BASED ENTRY POINT
;WHEN THAT LOADER BROUGHT IN CP/M
JMP LPTDEF 1,0 ;B: MINI DRIVE
;
PAGE
;COLD BOOT ENTRY POINT READS IN ALL OF CP/M INCLUDING BIOS
;BOOT IS DONE BY THE POWER ON BOOT OVERLAY PROM AT ADDRESS 0000H
;
BOOT:
IN RAMCTL
ORI 20H ;CLEAR RAM CONTROL PORT
OUT RAMCTL ;.TO TURN PROM BACK ON WHERE CP/M 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
;
;
JMP BOOT ;FROM COLD START LOADER
WBOOTE:
JMP WO TRACK ZERO
JMP SELDSK ;SELECT DISK DRIVE
JMP SETTRK ;SEEK TO TRACK IN REG A
JMP SETSEC ;SET SECTOR NUMBER
JMP SETDMA ;SET DISK STARTING ADR
JMP READ ;READ SELECTED SECTOR
JMP WRITE ;WRITE SELECTED
JMP LPTSTAT ;RETURN LIST STATUSIN ;GET CHARACTER FROM LIST SERIAL PORT
;
PAGE
;PARAMETER TABLES FOR TANDON 5 1/4 DOUBLE DENSITY
;DOUBLE SIDED 96 TRACKS PER INCH MINI FLOPPY DRIVES
;
DISKS 2 ;TWO MINI DRIVES SUPPORTED
DISKDEF 0,1,32,,2048,304,128,128,2 ;A: MINI DRIVE
DISK
JMP 0000H ;TO BASE OF PROM LOADER
;
;
;SOFT COLD BOOT ENTRY POINT
;
CBCPMIN: ;PROM BOOTED CP/M ENTRY POINT
LXI B,ENDZ-STARTZ ;GET LENGTH OF ZERO AREA
LXI H,STARTZ ;GET SCRATCH ADDRESS
BOOTL:
XRA A ;MAKE ZERO FILL
MOV M,A ;PUT ZERO IN MEMORY
INX H ;INCREMENT POINTER
DCX B ;DECREMENT COUNTER
MOV A,B
ORA C
JNZ BOOTL ;LOOP TILL DONE
;
MVI A,DEFDSK ;SET UP DEFAULT BOOT DISK
STA SEKDSK
STA TEMPDSK ;SAVE TEMPORARY DISK LOCATION
XRA A
STA IOBYTE ;CLEAR I/O BYTE EFAULT DMA ADDRESS
SHLD DMAADR
;
MVI C,COMPEN+MINIEN+DENSEL
CALL MMODE ;SET MINI FLOPPY OPERATION MODE
;
LDA TEMPDSK ;GIVE CP/M "DISK SELECTED" NUMBER
MOV C,A ;PASS TO CCP IN C
;
JMP CCP ;OFF TO CCP
;
;
;
;READ ALL OF CP/M BACK IN OCATED COUNT
MVI E,NSECTS ;GET NUMBER SECTORS FOR CP/M READ
;
CALL GETSYS ;GO READ ALL EXCEPT BIOS
ORA A
PUSH PSW
CNZ EREXIT ;TAKE CARE OF ERROR
POP PSW
JNZ WBOOT ;TRY WARM BOOT AGAIN IF BAD LOAD
JMP GOCPM ;GO BACK TO CP/M
;
PAGLE INPUT ROUTINE
; GETS CHAR TO (A) REGISTER
;
CI:
CALL CSTS ;CHECK CONSOLE STATUS
ORA A ;SET FLAGS
JZ CI ;WAIT TILL READY
CALL CONIN ;GO TO I/O MODULE FOR READY CHAR
;
IF DELBS ;SELECTED DELETE SUBSTITUTE TO BS?
CPI RUBOUT ;CHECK IF
;
LXI H,SMSG ;PRINT OPENING MESSAGE
CALL PRTMSG ;PRINT MESSAGE STRING
;
GOCPM:
MVI A,0C3H ;PUT JMP TO WBOOT
STA BASE ;ADR AT ZERO
LXI H,WBOOTE
SHLD BASE+1
STA BASE+5
LXI H,BDOS ;PUT JUMP TO BDOS
SHLD BASE+6
LXI H,DFDMA ;SET DEXCEPT BIOS, THEN JUMP TO CCP
;
WBOOT:
LXI SP,STACK ;SET STACK POINTER
LDA LOGDSK ;SAVE CURRENT "LOGGED DISK SELECT"
STA TEMPDSK
XRA A ;SELECT HEAD ZERO ("SELECTED DISK = A:")
STA HSTACT ;SET HOST BUFFER INACTIVE
STA UNACNT ;CLEAR UNALLE
;CONSOLE STATUS ROUTINE
; CHECKS MINI FLOPPY MOTOR ON STATUS
; RETURNS A=00H IF NO INPUT READY
; RETURNS A=FFH IF INPUT READY
;
CSTS:
CALL MMOFF ;SEE IF MINI MOTORS NEED SHUTOFF
CALL CONSTAT ;TO I/O MODULE FOR INPUT STATUS
RET
;
;
;CONSOINPUT WAS A DELETE
RNZ
MVI A,BS ;SUBSTITUTE THE BACK SPACE IF SO
ENDIF
;
RET
;
;
;CONSOLE OUTPUT ROUTINE
; SENDS CHAR IN (C) REGISTER
;
CO:
MOV A,C ;STRIP PARITY FOR CD 100M
ANI 07FH
MOV C,A
CALL CONOUT ;SEND CHARACTER VIA I/O MODULE
CALL MMOFF ;SEE IF MINI FLOPPY MOTORS NEED SHUTOFF
RET
;
PAGE
;PUNCH PAPER TAPE, DEFAULT IS CONSOLE
;
PUNCH:
CALL LPTOUT ;SEND PUNCH TO CONSOLE
RET ;RETURN FROM PUNCH
;
;
;READ PAPER TAPE, DEFAULT IS CONSOLE
;
READER:
CALL LIN H&L REGS., IF ERROR
CPI 01H+1 ;IS SELECT MORE THAN MAX TABLE ENTRY
RNC ;RETURN WITH ERROR, IF NOT VALID TABLE ENTRY
;
PUSH H ;CHECK IF VALID FROM TABLE
ADD A ;MAKE UNIT SELECT TABLE INDEX
ADD A
MOV L,A
LXI D,DSTAB ;DRIVE SETUP TABLEUNIT SELECT CODE
STA SEKDSK
;
XCHG ;IS A LEGAL SELECT THEN PROCESS
;PARAMETERS
INX H ;POINT TO DRIVE PHYSICAL UNIT NUMBER
;DRIVE PHYSICAL UNIT NUMBER NOT USED
;TILL I/O ROUTINES WHEN THE DRIVE IS USED
;
INX H ;POINT TO UNUSED TO TABLE
XRA A ;SET A REG. = 00
RET ;RETURN FROM SELDSK
;
PAGE
;VALID DISK DRIVE SELECT TABLES
;
; TABLE ENTRIES CONTAIN VALUES FOR VARIOUS DISK CONFIGURATIONS
; AND ALLOW QUICK INDEXING TO THE DRIVE SELECT CODE PARAMETERS.
;
; EACH PTIN ;READ FROM CONSOLE
RET ;RETURN FROM READER
;
;
;
;
;SELECT UNIT NUMBER ACCORDING TO REGISTER C
;
; WHERE: 00 = MINI DRIVE 0 (DISK A:)
; 01 = MINI DRIVE 1 (DISK B:)
;
SELDSK:
MOV A,C ;GET NEW UNIT NUMBER
LXI H,0 ;RETURN 0000 BASE
DAD D ;(HL) = SELECTED DRIVE POINTER
MOV A,M ;GET VALIDITY BYTE THIS UNIT
ORA A ;ZERO = ILLEGAL
XCHG ;SAVE POINTER IF NO EXIT
POP H ;GET BACK H&L TO ZERO FOR ERROR EXIT
RZ ;RETURN ON ILLEGAL UNIT
;
MOV A,C ;SET SEKDSK TO CP/M MINI/HARD FLAG
;
INX H ;POINT TO CP/M DISK PARAMETER TABLE INDEX
MOV L,M ;MAKE DOUBLE TABLE INDEX*16
MVI H,00H
;
REPT 4 ;SHIFT LEFT 4 (*16)
DAD H
ENDM
;
LXI D,DPBASE ;D&E REGS. = DISK PARAMETER BASE
DAD D ;H&L REGS. = BIAS OFFSET INENTRY CONSISTS OF:
; FIRST BYTE: LEGAL/ILLEGAL 0=ILLEGAL, 0FFH=LEGAL
; SECOND BYTE: PHYSICAL UNIT SELECT CODE 00 TO 03
; THIRD BYTE: MINI/HARD FLAG 0=HARD UNIT, 0FFH=MINI FLOPPY
; (NOT USED IN MINI ONLY BIOS)
; FOURTH BYTE: DISK PARAMETER TABLE INDEX (FROM DISKDEF)
;
DSTAB:
DB 0FFH,000H,000H,000H ;MINI FLOPPY DISK UNIT 0
DB 0FFH,001H,000H,001H ;MINI FLOPPY DISK UNIT 1
;
;
;SUBROUTINE TO GET THE PHYSICAL DRIVE NUMBER OUT OF THE DRIVE
;SELECT PARAMETER TABLE INTO (A)
;
GEUMBER INTO (A)
RET
;
PAGE
;
;MOVE DISK TO TRACK ZERO
;
HOME:
LDA HSTWRT ;CHECK FOR PENDING WRITE
ORA A
JNZ HOMEIT
STA HSTACT ;CLEAR HOST ACTIVE FLAG
;
HOMEIT:
LXI H,0000H ;ITS LIKE WE ARE GOING TO TRACK 0
SHLD SEKTRK
;
XRA A NI FLOPPY AT THE PHYSICAL SECTOR BASIS IN THE MINI
; FLOPPY READ/WRITE SETUP ROUTINE.
;
SECTRAN:
MOV H,B
MOV L,C
RET ;RETURN FROM SECTRAN
;
;
;SET DISK SECTOR NUMBER
;
SETSEC:
MOV A,C ;GET SECTOR NUMBER
STA SEKSEC ;SECTOR TO SEEK
COUNT
STA UNACNT
MVI A,1
STA READOP ;READ OPERATION
STA RSFLAG ;MUST READ DATA
MVI A,WRUAL
STA WRTYPE ;TREAT AS UNALLOCCATED
JMP RWOPER ;TO PERFORM THE READ
;
;
;WRITE THE SELECTED CP/M 2.2 SECTOR
;
WRITE:
XRA A ;0 TO A REG.
STTDRNO:
LDA HSTDSK ;GET UNIT CP/M THINKS WE HAVE
ADD A
ADD A ;SETUP INDEX INTO FOUR BYTE TABLE
;ENTRIES
MOV C,A
MVI B,0
LXI H,DSTAB+1 ;BASE ADDRESS FOR ENTRIES OF PHYSICAL
;DRIVE ADDRESS TRANSLATION
DAD B
MOV C,M ;GET PHYSICAL N;FLAG NO ERRORS
RET
;
;
;SET TRACK NUMBER SPECIFIED BY B&C REGS.
;
SETTRK:
MOV H,B
MOV L,C
SHLD SEKTRK ;TRACK TO SEEK
RET
;
PAGE
;TRANSLATE THE SECTOR GIVEN BY B&C REGS.
;
; NO TRANSLATE DONE AT THIS TIME. WE WILL TRANSLATE THE
; MIRET ;RETURN FROM SETSEC
;
;
;SET DISK DMA ADDRESS
;
SETDMA:
MOV H,B ;MOVE B&C TO H&L
MOV L,C
SHLD DMAADR ;PUT AT DMA ADR ADDRESS
RET ;RETURN FROM SETDMA
;
PAGE
;READ THE SELECTED CP/M 2.2 SECTOR
;
READ:
XRA A ;CLEAR UNALLOCATEDA READOP ;NOT A READ OPERATION
MOV A,C ;WRITE TYPE IN C
STA WRTYPE
CPI WRUAL ;WRITE UNALLOCATED?
JNZ CHKUNA ;CHECK FOR UNALLOCATED
;
;
;WRITE TO UNALLOCATED, SET PARAMETERS
;
MVI A,BLKSIZ/128 ;NEXT UNALLOCATED RECORDS
STA UNACNT
LDA SEKDSK ;DISK TO SEEK
STA UNADSK ;UNADSK = SEKDSK
LHLD SEKTRK
SHLD UNATRK ;UNATRK = SECTRK
LDA SEKSEC
STA UNASEC ;UNASEC = SEKSEC
;
PAGE
;CHECK FOR WRITE TO UNALLOCATED SECTOR
;
CHKUNA:
LDA UNACNT ;ANY UNALLOCATED REMAINING?
ORA A
TRKCMP ;SEKTRK = UNATRK?
JNZ ALLOC ;SKIP IF NOT
;
;
;TRACKS ARE THE SAME
;
LDA SEKSEC ;SAME SECTOR?
LXI H,UNASEC
CMP M ;SEKSEC = UNASEC?
JNZ ALLOC ;SKIP IF NOT
;
PAGE
;MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE
;
INR M ;UNASEH FOUND, MARK AS UNNECESSARY READ
;
NOOVF:
XRA A ;0 TO A REG.
STA RSFLAG ;RSFLAG = 0
JMP RWOPER ;TO PERFORM THE WRITE
;
;
;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
;
ALLOC:
XRA A ;0 TO A REG.
STA UNACNT ;UNACNT = 0
INR A ;1 TO ;CARRY = 0
RAR ;SHIFT RIGHT
ENDM
;
;
;OUR DISK CONTROLLER NUMBERS ITS RECORDS FROM 1 AND NOT ZERO
;SO FIXUP THE "SEKHST" SECTOR NUMBER
;
INR A
STA SEKHST ;HOST SECTOR TO SEEK
;
;
;ACTIVE HOST SECTOR?
;
LXI H,HSTACT ;HOST ACTIVE FLAGJZ ALLOC ;SKIP IF NOT
;
;
;MORE UNALLOCATED RECORDS REMAIN
;
DCR A ;UNACNT = UNACNT-1
STA UNACNT
LDA SEKDSK ;SAME DISK?
LXI H,UNADSK
CMP M ;SEKDSK = UNADSK?
JNZ ALLOC ;SKIP IF NOT
;
;
;DISKS ARE THE SAME
;
LXI H,UNATRK
CALL SEKC = UNASEC+1
MOV A,M ;END OF TRACK?
PUSH B
MVI B,FDSPT ;USE MINI DISK SPT
CMP B
POP B
JC NOOVF ;SKIP IF NO OVERFLOW
;
;
;OVERFLOW TO NEXT TRACK
;
MVI M,0 ;UNASEC = 0
LHLD UNATRK
INX H
SHLD UNATRK ;UNATRK = UNATRK+1
;
;
;MATCA REG.
STA RSFLAG ;RSFLAG = 1
;
PAGE
;
;COMMON CODE FOR READ AND WRITE FOLLOWS:
;
RWOPER: ;ENTER HERE TO PERFORM THE READ/WRITE
XRA A ;ZERO TO A REG.
STA ERFLAG ;NO ERRORS (YET)
LDA SEKSEC ;COMPUTE HOST SECTOR
;
REPT SECSHF
ORA A
MOV A,M
MVI M,1 ;ALWAYS BECOMES 1
ORA A ;WAS IT ALREADY?
JZ FILHST ;FILL HOST IF NOT
;
;
;HOST BUFFER ACTIVE, SAME AS SEEK BUFFER?
;
LDA SEKDSK
LXI H,HSTDSK ;SAME DISK?
CMP M ;SEKDSK = HSTDSK?
JNZ NOMATCH
;
PAGE
;SAME DISK, SAME TRACK?
;
LXI H,HSTTRK
CALL SEKTRKCMP ;SEKTRK = HSTTRK?
JNZ NOMATCH
;
;
;SAME DISK, SAME TRACK, SAME BUFFER?
;
LDA SEKHST
LXI H,HSTSEC ;SEKHST = HSTSEC?
CMP M
JZ MATCH ;SKIP IF MATCH
;
;
;PROPER DISK, BUT NOT CORRECT SECTOR
;
NOMAT ;YES, IF 1
XRA A ;0 TO A REG.
STA HSTWRT ;NO PENDING WRITE
;
PAGE
;COPY DATA TO OR FROM BUFFER
;
MATCH:
LDA SEKSEC ;MASK BUFFER NUMBER
ANI SECMSK ;LEAST SIGNIF BITS
MOV L,A ;READY TO SHIFT
MVI H,0 ;DOUBLE COUNT
;
REPT 7 ;SHIFWMOVE ;SKIP IF READ
;
;
;WRITE OPERATION, MARK AND SWITCH DIRECTION
;
MVI A,1
STA HSTWRT ;HSTWRT = 1
XCHG ;SOURCE/DESTINATION SWAP
;
PAGE
;C INITIALLY 128, DE IS SOURCE, HL IS DESTINATION
;
RWMOVE:
LDAX D ;SOURCE CHARACTER
INX D
ST BUFFER FOR DIRECTORY WRITE
;
ORA A ;ERRORS?
RNZ ;SKIP IF SO
XRA A ;0 TO A REG.
STA HSTWRT ;BUFFER WRITTEN
CALL WRITEHST
LDA ERFLAG
RET
;
;
;UTILITY SUBROUTINE FOR 16-BIT COMPARE
;
SEKTRKCMP: ;HL = .UNATRK OR .HSTTRK, COMPARE TCH:
LDA HSTWRT ;HOST WRITTEN?
ORA A
CNZ WRITEHST ;CLEAR HOST BUFF
;
;
;MAY HAVE TO FILL THE HOST BUFFER
;
FILHST:
LDA SEKDSK
STA HSTDSK
LHLD SEKTRK
SHLD HSTTRK
LDA SEKHST
STA HSTSEC
LDA RSFLAG ;NEED TO READ?
ORA A
CNZ READHST LEFT 7
DAD H
ENDM
;
;
;HL HAS RELATIVE HOST BUFFER ADDRESS
;
LXI D,HSTBUF
DAD D ;HL = HOST ADDRESS
XCHG ;NOW IN DE
LHLD DMAADR ;GET/PUT CP/M DATA
MVI C,128 ;LENGTH OF MOVE; CP/M SECTOR SIZE
LDA READOP ;WHICH WAY?
ORA A
JNZ RMOV M,A ;TO DESTINATION
INX H
DCR C ;LOOP 128 TIMES
JNZ RWMOVE
;
;
;DATA HAS BEEN MOVED TO/FROM HOST BUFFER
;
LDA WRTYPE ;WRITE TYPE
CPI WRDIR ;TO DIRECTORY?
LDA ERFLAG ;IN CASE OF ERRORS
RNZ ;NO FURTHER PROCESSING
;
;
;CLEAR HO
;..WITH SEKTRK
XCHG
LXI H,SEKTRK
LDAX D ;LOW BYTE COMPARE
CMP M ;SAME?
RNZ ;RETURN IF NOT
;
PAGE
;LOW BYTES EQUAL, TEST HIGH FIRST
;
INX D
INX H
LDAX D
CMP M ;SETS FLAGS
RET
;
;
WRITEHST: ;PERFORMS THE PHYSICAL WRITE
;TO THE HOST DISK
;
;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER,
;HSTSEC = HOST SECT NUMBER. WRITE "HSTSIZ" BYTES
;FROM HSTBUF AND RETURN ERROR FLAG IN ERFLAG.
;RETURN ERFLAG NON-ZERO IF ERROR
;
WRTSEC:
CALL MIOPB ;SETUP MINI FLFLAG
RET
;
PAGE
READHST: ;PERFORMS THE PHYSICAL READ FROM
;..THE HOST DISK
;
;HSTDSK = HOST DISK NUMBER, HSTTRK = HOST TRACK NUMBER,
;HSTSEC = HOST SECT NUMBER. READ "HSTSIZ" BYTES
;INTO HSTBUF AND RETURN ERROR FLAG IN ERFLAG.
;
READSEC
PAGE
;READ/WRITE BIOS ERROR PRINT ROUTINE
;WAITS FOR USER RESPONSE ON CONSOLE AFTER PRINTING MESSAGE
;AND THEN RETURNS TO THE CALLER
;
EREXIT:
STA IOERR ;SAVE ERROR STATUS
LXI H,ERRMSF ;USE MINI FLOPPY ERROR MESSAGE
CALL PRTMSG
LXI H,ERRM
ADI 'A'
MOV C,A
CALL CONOUT
LXI H,ERRMS3 ;PRINT MESSAGE CLOSE
CALL PRTMSG
CALL CONIN ;WAIT FOR OPERATOR RESPONSE
CPI 'C'-040H ;IF CTL-C THEN GO DO WARM BOOT
JZ WBOOT
;
LXI H,ERRMS4
CALL PRTMSG
RET ;BACK TO CP/M
;
PAGE
;ERROR OPPY PARAMETERS
CALL MWRIT
ORA A
JNZ WRTERR ;EXIT FOR WRITE ERROR
;
WRTOK:
XRA A
STA ERFLAG ;RESET ERROR FLAG
RET ;RETURN FROM "WRITEHST", IF O.K.
;
WRTERR:
CALL EREXIT ;PRINT BIOS ERROR MESSAGE
MVI A,01H ;SET ERROR FLAG
STA ER:
CALL MIOPB ;SETUP MINI FLOPPY IOPB
CALL MREAD ;GO READ THAT SECTOR
ORA A
JNZ RDERR ;EXIT FOR READ ERROR
;
RDOK:
XRA A
STA ERFLAG
RET
;
RDERR:
CALL EREXIT ;PRINT BIOS ERROR MESSAGE
MVI A,01H ;SET ERROR FLAG
STA ERFLAG
RET
;S1 ;PRINT COMMON PART OF MESSAGE
CALL PRTMSG
LDA IOERR ;PRINT ERROR CODE
PUSH PSW
RRC
RRC
RRC
RRC
CALL HEXOUT
POP PSW
CALL HEXOUT
LXI H,ERRMS2 ;PRINT REST OF MESSAGE
CALL PRTMSG
LDA HSTDSK ;PRINT CP/M DRIVE DESIGNATOR WITH ERRORROUTINE MESSAGES
;
ERRMSF:
DB CR,LF,CR,LF,' *** MINI FLOPPY',0
ERRMS1:
DB ' DISK I/O ERROR - CODE(',0
ERRMS2:
DB ') - DRIVE ',0
ERRMS3:
DB ': *** ',0
ERRMS4:
DB CR,LF,0
;
;
;SUBROUTINE TO SEND A HEX CHAR TO THE CONSOLE
;
HEXOUT:
ANI 0FH ;LOW NIBBLE ONLY
CPI 0AH ;GREATER THAN 9?
JM HEX1
ADI 07H ;ADD OFFSET FOR A-F
HEX1:
ADI 030H ;ADD IN ASCII OFFSET
MOV C,A ;PRINT RESULT
CALL CONOUT
RET
;
PAGE
;*******************************************************************YSGEN SIZE.
; PUT HERE AS SUBROUTINE SO CAN BE USED BY WARM BOOT ROUTINES
; IN THE BIOS. ROUTINE USED ONLY FOR MINI FLOPPY DISK.
;
GETSYS:
PUSH D ;SAVE CALLERS RECORD COUNT
MVI A,DEFDSK ;SELECT DEFAULT DRIVE
STA HSTDSK ;SET DRIVE NUMBER FOR I/ETUP MINI I/O
CALL MREAD ;GO READ T0/S1
ORA A ;CHECK OP STATUS
POP D
RNZ ;BACK TO CALLER IF FIRST SECTOR NOT READ
;
PAGE
;FIRST SECTOR IN NOW GO READ THE REST OF ALL THIS
;
LHLD HSTBUF ;GET BASE ADDRESS OF LOAD
MVI D,02H ;START LOAD LL MIOPB ;SET MINI I/O PARAMETER BLOCK
POP B
CALL MBADDR ;RESET IOPB ADDRESS TO RIGHT VALUE
CALL MREAD ;GO READ NEXT SECTOR
POP H ;GET BACK LOAD ADDRESS
POP D ;GET BACK REC / REC CNT
POP B ;GET BACK CYL
;
ORA A ;CHECK COMMAND COMPLETI**
;
;
; READ SEQUENTIAL DISK SECTORS INTO MEMORY AS SPECIFIED BY ENTRY
; PARAMETERS. ENTRY WITH (E) REGISTER EQUAL TO THE NUMBER OF 512
; BYTE SECTORS TO READ. TRACK 0 SECTOR 1 IS READ TO GET LOAD
; PARAMETERS FOR BASE ADDRESS THAT MAY CHANGE WITH SO
MOV C,A
CALL MUNIT
CALL MREST ;RESTORE DRIVE
ORA A
POP D
RNZ ;BACK TO BOOT ROUTINE IF ERROR
;
PUSH D ;SAVE CALLERS RECORD COUNT AGAIN
MVI A,01H ;START WITH SECTOR 1
STA HSTSEC
MVI A,00H ;ON TRACK 1
STA HSTTRK
CALL MIOPB ;SWITH SECOND SECTOR
LXI B,0000H ;INITIAL WITH CYLINDER 0
GETSYS1:
PUSH B ;SAVE CYL
PUSH D ;SAVE RECORD NUMBER/REC COUNT
PUSH H ;SAVE LOAD ADDRESS
MOV A,C ;SET TRACK NUMBER
STA HSTTRK
MOV A,D ;SET RECORD NUMBER
STA HSTSEC
PUSH H
CAON STATUS
RNZ ;BACK TO CALLER IF ERROR
;
PUSH B
LXI B,HSTSIZ ;GET ADDRESS INDEX
DAD B ;(HL) HAS NEW LOAD ADDRESS
POP B
INR D ;SET FOR NEXT RECORD
MOV A,D ;CHECK IF PAST END OF CYLINDER
CPI FDSPT+1
JNZ SAMTRK ;STILL ON SAME TRACK
;
INX B ;INCREMENT CYLINDER NUMBER
MVI D,01H ;SET RECORD BACK TO START OF TRACK
SAMTRK:
DCR E ;SEE IF ALL SECTORS IN YET
JNZ GETSYS1 ;GO DO MORE IF NOT DONE YET
XRA A
RET ;RETURN GOOD LOAD CODE
;
PAGE
;********************************1H ;FIND OUT WHAT THE SIDE NUMBER IS
MOV C,A
CALL MSURF ;SET MINI HEAD NUMBER
POP PSW
ORA A
RAR ;DIVIDE TRACK BY 2
MOV C,A ;SEND PHYSICAL TRACK TO IOPB
CALL MCYL
;
MVI C,00H ;SET SIZE CODE TO 256 BYTES
CALL MSSIZE
MVI C,02H ;SETBASE ADDRESS
DAD B
MOV C,M
CALL MREC ;SET ACTUAL SECTOR TO START READ UPON
LXI B,HSTBUF ;SET FLOPPY BUFFER ADDRESS
CALL MBADDR
RET
;
PAGE
;MINI FLOPPY PHYSICAL SECTOR TRANSLATE TABLE
;
MFSTRAN:
DB 1,2,5,6,9,10,13,14,3,4,7,8,11,12,15,16 IF END OF STRING FLAG
MOV C,A ;CHARACTER IN C REG., FOR CONSOLE OUTPUT
PUSH H ;SAVE OUT POINTER
CALL CONOUT ;PRINT CHARACTER, CONSOLE OUTPUT
POP H ;GET BACK MESSAGE POINTER
INX H ;BUMP MESSAGE POINTER
JMP PRTMSG
;
;
;FBIOS SIGNON MESSA******************************************
;
;
;MINI FLOPPY I/O PARAMETER BLOCK SET UP ROUTINE
;
MIOPB:
CALL GETDRNO ;GET PHYSICAL DRIVE NUMBER FROM
CALL MUNIT ;..FROM DRIVE SELECT TABLE
LDA HSTTRK ;GET AND SET TRACK NUMBER
PUSH PSW
ANI 0 SECTOR COUNT TO 2
CALL MCNT
;
LDA HSTSEC ;CONVERT SECTOR NUMBER TO PROPER SKEW
ORA A ;CONVERT TO PAIRED ODD BASED
RAL
DCR A
DCR A ;NOW ZERO BASED FOR INDEXING
MVI B,00H
MOV C,A ;DOUBLE BYTE INDEX WORD
LXI H,MFSTRAN ;TRANSLATE TABLE
;NOTE THAT ONLY ODD SECTORS ALLOWED
;
;
;*************************************************************************
;
;
;PRINT THE MESSAGE AT H&L UNTIL A ZERO
;
;
PRTMSG:
MOV A,M ;GET CHARACTER TO PRINT
ORA A ;SET FLAGS
RZ ;RETURN,GE
;
SMSG: DB CR,LF,ESC,'Æ7;2m','CHRISTIAN ROVSING A/S '
DB (MSIZE+3)/10+'0',(MSIZE+3) MOD 10+'0'
DB 'K CP/M VER 2.2 '
DB MONTH/10+'0',MONTH MOD 10+'0'
DB '-'
DB DAY/10+'0',DAY MOD 10+'0'
DB '-'
DB YEAR/10+'0',YEAR MOD 10+'0'
DB CR,LF,ESC,'Æm','TANDON TM100 96 TPI 5 1/4 MINI '
DB 'FLOPPY BIOS, VER. '
DB VERSION/10+'0','.',VERSION MOD 10+'0'
DB 0
;
PAGE
;****************************************************************************
;
;
; STORAGE AREA FOR VA;
IOERR:
DS 1 ;DISK I/O ERROR TYPE
;
;
;
;HOST DISK BLOCKING/DE-BLOCKING DATA AREA
;
TEMPDSK:
DS 1 ;TEMPORARY STORAGE FOR LOGGED DISK
;
;
SEKDSK:
DS 1 ;SEEK DISK NUMBER
SEKTRK:
DS 2 ;SEEK TRACK NUMBER
SEKSEC:
DS 1 ;SEEK SECTONALLOCATED RECORD COUNT
UNADSK:
DS 1 ;LAST UNALLOCATED DISK
UNATRK:
DS 2 ;LAST UNALLOCATED TRACK
UNASEC:
DS 1 ;LAST UNALLOCATED SECTOR
;
ERFLAG:
DS 1 ;ERROR REPORTING
RSFLAG:
DS 1 ;READ SECTOR FLAG
READOP:
DS 1 ;1 IF READ OPE;
IMGSIZ EQU HSTSIZ-CCP
;
;
;SCRATCH RAM AREA FOR BDOS USE
;
ENDEF ;LET DISKDEF FIXUP BDOS BUFFERS
;
;
END
;
;
;+++...END OF FILE
«eof»