Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM I/MPM I SOURCE/12/axios.asm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

2398 lines
54 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

TITLE 'XIOS200, Copyright 1979, ALTOS COMPUTER SYSTEMS'
;-----------------------------------------------------------------------
;
;
; ALTOS COMPUTER SYSTEMS
; 2338A WALSH AVENUE
; SANTA CLARA, CALIFORNIA 95050
;
; (408) 244-5766
;
;
; Copyright 1979, ALTOS COMPUTER SYSTEMS
;
; This program is a copyright program product of
; ALTOS COMPUTER SYSTEMS and is distributed to the
; owners of ALTOS SUN SERIES 8000 computers for
; use on those systems only. Any other use of this
; software constitutes a breach of the copyright
; license to the purchaser.
;
; VERSION NUMBER: 1.00
; VERSION DATE: DECEMBER 31, 1979
; . Add support for CP/M version 2.0
; . Add support for Hard disk drives
; . Add support for disk MODE selection
; . Provide compatability MODE for 1.4 operation
; . Remove CTC/1791 counter reset
;
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;
; Mode 0 IBM single density
; 1 ALTOS double density Version 2.0
; 2 ALTOS double density Version 1.4
; 3 ALTOS hard disk Version 2.0 (8 MEG AT 000)
; 4 ALTOS HARD DISK VERSION 2.0 (8 MEG AT 512)
; 5 ALTOS HARD DISK VERSION 2.0 (8 MEG AT 1024)
; 6 ALTOS HARD DISK VERSION 2.0 (4 MEG AT 512)
;
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;
; ASSEMBLER CONTROL STATEMENTS
;
;-----------------------------------------------------------------------
MACLIB DISKDEF
MACLIB Z80S
TRUE EQU 0FFFFH ;VALUE FOR TRUE
FALSE EQU NOT TRUE ;VALUE FOR FALSE
;-----------------------------------------------------------------------
;
; THE FOLLOWING EQUATES ARE USER MODIFIABLE BASED ON THE
; PARTICULAR USER SYSTEM AND OPTIONS SELECTED.
;
;-----------------------------------------------------------------------
DMA EQU TRUE ;DMA HARDWARE SUPPORT ??
HARDSK EQU TRUE ;HARD DISK SUPPORT
;-----------------------------------------------------------------------
;
; THE FOLLOWING CONSTANTS APPLY TO THE DEBLOCKING OF
; SECTORS LARGER THAN 128 FOR THE ALTOS DOUBLE DENSITY
; AND THE ALTOS HARD DISK.
;
;-----------------------------------------------------------------------
BLKSIZ EQU 16384 ;CP/M ALLOCATION SIZE
HSTSIZ EQU 1024 ;HOST DISK SECTOR SIZE
HSTSPT EQU 16 ;HOST DISK SECTORS PER TRACK
HSTBLK EQU HSTSIZ/128 ;CP/M SECTORS PER HOST BUFFER
CPMSPT EQU HSTBLK * HSTSPT ;CP/M SECTORS PER TRACK
SECMSK EQU HSTBLK - 1 ;SECTOR MASK
SECSHF EQU 3 ;LOG2(HHSTBLK)
PAGE
;-----------------------------------------------------------------------
;
; THE FOLLOWING EQUATES APPLY TO THE RELOCATABILITY
; OF THE CBIOS AND SHOULD NOT BE USER ALTERED.
;
;-----------------------------------------------------------------------
RELOC EQU TRUE ;RELOCATABLE VERSION ??
;-----------------------------------------------------------------------
IF HARDSK
MAXDSK EQU 12 ;MAXIMUM NUMBER OF LOGICAL DRIVES
ELSE
MAXDSK EQU 4 ;MAXIMUM NUMBER OF LOGICAL DRIVES
ENDIF
IF RELOC
ORG 0000H
ELSE
ORG 0C000H
ENDIF
BASE EQU $
;-----------------------------------------------------------------------
WRALL EQU 0 ;WRITE TO ALLOCATED
WRDIR EQU 1 ;WRITE TO DIRECTORY
WRUAL EQU 2 ;WRITE TO UNALLOCATED
NMBCNS EQU 4 ; NUMBER OF CONSOLES
POLL EQU 131 ; XDOS POLL FUNCTION
FLAGWT EQU 132 ; XDOS FLAG WAIT FUNCTION
FLAGST EQU 133 ; XDOS FLAG SET FUNCTION
PLLPT EQU 0 ; POLL PRINTER
PLCO0 EQU PLLPT+1 ; POLL CONSOLE OUT #0 (CRT:)
PLCO1 EQU PLCO0+1 ; POLL CONSOLE OUT #1 (CRT:)
PLCO2 EQU PLCO1+1 ; POLL CONSOLE OUT #2 (CRT:)
PLCO3 EQU PLCO2+1 ; POLL CONSOLE OUT #3 (CRT:)
PLCI0 EQU PLCO3+1 ; POLL CONSOLE IN #0 (CRT:)
PLCI1 EQU PLCI0+1 ; POLL CONSOLE IN #1 (CRT:)
PLCI2 EQU PLCI1+1 ; POLL CONSOLE IN #2 (CRT:)
PLCI3 EQU PLCI2+1 ; POLL CONSOLE IN #3 (CRT:)
MEMPORT EQU 009H ; MEMORY SELECT PORT
MEMSK EQU 002H ; MEMORY SELECT MASK
PAGE
;-----------------------------------------------------------------------
;
; JUMP VECTORS FOR ENTRIES TO CBIOS ROUTINES
;
;-----------------------------------------------------------------------
; EXTERNAL JUMP TABLE (BELOW XIOS BASE)
PDISP EQU $-3
XDOS EQU PDISP-3
JMP COLDSTART ;COLD START
WBOTE:
JMP WARMSTART ;WARM START
JMP CONST ;CONSOLE STATUS
JMP CONIN ;CONSOLE CHARACTER IN
JMP CONOUT ;CONSOLE CHARACTER OUT
JMP LIST ;LIST CHARACTER OUT
JMP RTNEMPTY ;PUNCH NOT IMPLEMENTED
JMP RTNEMPTY ;READER NOT IMPLEMENTED
JMP HOMEIT ;MOVE HEAD TO HOME
JMP SELDSK ;SELECT DISK
JMP SETTRK ;SET TRACK NUMBER
JMP SETSEC ;SET SECTOR NUMBER
JMP SETDMA ;SET DMA ADDRESS
JMP READ ;READ DISK
JMP WRITE ;WRITE DISK
JMP POLLPT ;LIST STATUS
JMP SECTRAN ;SECTOR TRANSLATE
; EXTENDED I/O SYSTEM JUMP VECTOR
JMP SELMEMORY ; SELECT MEMORY
JMP POLLDEVICE ; POLL DEVICE
JMP STARTCLOCK ; START CLOCK
JMP STOPCLOCK ; STOP CLOCK
JMP EXITREGION ; EXIT REGION
JMP MAXCONSOLE ; MAXIMUM CONSOLE NUMBER
JMP SYSTEMINIT ; SYSTEM INITIALIZATION
NOP ; NO JMP HERE
NOP ; FOR MP/M DELAY
NOP ;
JMP SETMOD ;ROUTINE TO SET DISK MODE
JMP RETMOD ;ROUTINE TO RETURN CURRENT MODE
COLDSTART:
WARMSTART:
MVI C,0 ; SEE SYSTEM INIT
; COLD & WARM START INCLUDED ONLY
; FOR COMPATIBILITY WITH CP/M
JMP XDOS ; SYSTEM RESET, TERMINATE PROCESS
RTNEMPTY:
XRA A ; NOT USED
RET ;
LAST:
ORG (((LAST-BASE)+0A2H) AND 0FF00H) +05EH
INTERUPT:
DW FLOPPY$INT ;FLOPPY DISK INTERRUPT
DW NULL$INT ;
DW NULL$INT ;
DW NULL$INT ;
DW INT1HND ;CTC INTERRUPT
DW NULL$INT ;
DW HARD$INT ;HARD DISK INTERRUPT
DW NULL$INT ;
DW NULL$INT ;
NULL$INT:
EI
RETI
PAGE
;-----------------------------------------------------------------------
;
; WORK AND CONTROL AREAS FOR CBIOS SERVICES
;
;-----------------------------------------------------------------------
TRK0: DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
SEL0: DB 004H,008H,010H,020H,010H,010H,010H,020H,020H,020H,010H,020H
MODE: DB 000H,000H,000H,000H,003H,004H,005H,003H,004H,005H,006H,006H
TCNT: DB 000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H
PCNT: DB 000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H
DISKNO: DB 000H ;CURRENT DRIVE NUMBER
TRAKNO: DB 000H ;CURRENT TRACK NUMBER
HEADNO: DB 000H ;CURRENT HEAD NUMBER
DMAADR: DW 000H ;CURRENT DMA ADDRESS
SECTNO: DB 000H ;CURRENT SECTOR NUMBER
DPEPTR: DW 000H ;CURRENT DPE ADDRESS
DBLKAD: DW 000H ;CURRENT EXTENSION ADDRESS
MPARMS: DW 000H ;MISC. PARAMETERS
HTK1: DB 10H ;HARD DISK # 1 TRACK
HTK2: DB 20H ;HARD DISK # 2 TRACK
;
; PARAMETER FLAGS
;
; 0100H = DOUBLE HEADED DRIVES
; 0200H = CENTRONICS PRINTER FOR LIST DEVICE
; 0400H = FOUR DRIVE SYSTEM [ A B C D ]
;-----------------------------------------------------------------------
;
;-----------------------------------------------------------------------
;
; NOTE:
; NO CHANGES ARE TO BE MADE TO THE ABSOLUTE LOCATIONS OF
; ANY FIELDS PRIOR TO THIS POINT. EXTERNAL PROGRAMS ARE
; DEPENDENT UPON THE LOCATION OF THE PRECEEDING DATA.
;
;-----------------------------------------------------------------------
NMIRTN: DB 0EDH,0A2H,0EDH,045H ;FAKE INI AND RETN INST
DMAS1: DB 0C3H,07DH ;FIRST PART OF DMA SETUP
DMASA: DW 000H ;ADDRESS FOR I/O
DMALEN: DW 1025-1 ;LENGTH FOR I/O
DMAS2H: DB 054H,0CEH,068H,0CEH,0A5H,020H ;HARD DISK SETUP
DMAS2F: DB 014H,028H,085H,007H ;FLOPPY DISK SETUP
DMAS3: DB 08AH,0CFH,001H,0CFH ;LAST PART OF DMA SETUP
DMAS3F: DB 001H ;001=READ, 005=WRITE
DB 0CFH,087H ;SETUP DMA, ENABLE
PAGE
;-----------------------------------------------------------------------
;
; CONTROL BLOCKS FOR DISK DRIVER
;
;-----------------------------------------------------------------------
DPBASE EQU $ ;START OF DISK PARAMETER BLOCKS
DPE0: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK
DW CSV0,ALV0 ;CHECK VECTOR, ALLOC VECTOR
DPE1: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK
DW CSV1,ALV1 ;CHECK VECTOR, ALLOC VECTOR
DPE2: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK
DW CSV2,ALV2 ;CHECK VECTOR, ALLOC VECTOR
DPE3: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK
DW CSV3,ALV3 ;CHECK VECTOR, ALLOC VECTOR
IF HARDSK
DPE4: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB3 ;DIR BUFF, PARM BLOCK
DW CSV4,ALV4 ;CHECK VECTOR, ALLOC VECTOR
DPE5: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB4 ;DIR BUFF, PARM BLOCK
DW CSV5,ALV5 ;CHECK VECTOR, ALLOC VECTOR
DPE6: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB5 ;DIR BUFF, PARM BLOCK
DW CSV6,ALV6 ;CHECK VECTOR, ALLOC VECTOR
DPE7: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB3 ;DIR BUFF, PARM BLOCK
DW CSV7,ALV7 ;CHECK VECTOR, ALLOC VECTOR
DPE8: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB4 ;DIR BUFF, PARM BLOCK
DW CSV8,ALV8 ;CHECK VECTOR, ALLOC VECTOR
DPE9: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB5 ;DIR BUFF, PARM BLOCK
DW CSV9,ALV9 ;CHECK VECTOR, ALLOC VECTOR
DPEA: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB6 ;DIR BUFF, PARM BLOCK
DW CSVA,ALVA ;CHECK VECTOR, ALLOC VECTOR
DPEB: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA
DW 0000H,0000H ;SCRATCH AREA
DW DIRBUF,DPB6 ;DIR BUFF, PARM BLOCK
DW CSVB,ALVB ;CHECK VECTOR, ALLOC VECTOR
ENDIF
;-----------------------------------------------------------------------
MODL0: DW XLT0,000H ;MODEL DPE FOR MODE 0
DW 000H,000H ;
DW DIRBUF,DPB0 ;
MODL1: DW XLT1,0000H ;MODEL DPE FOR MODE 1
DW 0000H,0000H ;
DW DIRBUF,DPB1 ;
MODL2: DW XLT2,0000H ;MODEL DPE FOR MODE 2
DW 0000H,0000H ;
DW DIRBUF,DPB2 ;
;-----------------------------------------------------------------------
XLT0: DB 1,7,13,19,25,5,11,17,23,3,9,15,21
DB 2,8,14,20,26,6,12,18,24,4,10,16,22
XLT1: DB 01,02,03,04,05,06,07,08,09,10,11,12,13
DB 14,15,16,17,18,19,20,21,22,23,24,25,26
DB 27,28,29,30,31,32,33,34,35,36,37,38,39
DB 40,41,42,43,44,45,46,47,48,49,50,51,52
XLT2: DB 01,02,03,04,05,06,07,08,09,10,11,12
DB 13,14,15,16,17,18,19,20,21,22,23,24
DB 25,26,27,28,29,30,31,32,33,34,35,36
DB 37,38,39,40,41,42,43,44,45,46,47,48
PAGE
;-----------------------------------------------------------------------
;
; THESE ARE THE DISK TYPE DEFINITION BLOCKS
; EACH OF WHICH CORRESPONDS TO A PARTICULAR MODE.
;
;-----------------------------------------------------------------------
DPB0: EQU $ ;VERSION 2.0, IBM SINGLE DENSITY
DW 26 ;SECTORS PER TRACK
DB 3 ;BLOCK SHIFT
DB 7 ;BLOCK SHIFT MASK
DB 0 ;EXTENT MASK
DW 242 ;DISK SIZE MINUS 1
DW 63 ;DIRECTORY MAX
DB 192 ;ALLOC0
DB 0 ;ALLOC1
DW 16 ;CHECK AREA SIZE
DW 2 ;OFFSET TO START TRACK
DPB1: EQU $ ;VERSION 2.0, IBM DOUBLE DENSITY
DW 52 ;SECTORS PER TRACK
DB 4 ;BLOCK SHIFT
DB 15 ;BLOCK SHIFT MASK
DB 1 ;EXTENT MASK
DW 242 ;DISK SIZE MINUS 1
DW 127 ;DIRECTORY MAX
DB 192 ;ALLOC0
DB 0 ;ALLOC1
DW 32 ;CHECK AREA SIZE
DW 2 ;OFFSET TO START TRACK
DPB2: EQU $ ;VERSION 1.4 ALTOS DOUBLE DENSITY
DW 48 ;SECTORS PER TRACK
DB 4 ;BLOCK SHIFT
DB 15 ;BLOCK SHIFT MASK
DB 0 ;EXTENT MASK (1.4 COMPATABILITY)
DW 224 ;DISK SIZE MINUS 1
DW 95 ;DIRECTORY MAX
DB 192 ;ALLOC0
DB 0 ;ALLOC1
DW 24 ;CHECK AREA SIZE
DW 2 ;OFFSET TO START TRACK
IF HARDSK
DPB3: DISKDEF 3,0,127,,16384,512,256,0,1
DPB4: DISKDEF 4,0,127,,16384,512,256,0,513
DPB5: DISKDEF 5,0,127,,16384,512,256,0,1025
DPB6: DISKDEF 6,0,127,,16384,288,256,0,513
ENDIF
PAGE
;-----------------------------------------------------------------------
;
; DISK ACCESS ROUTINES
;
;-----------------------------------------------------------------------
SELDSK:
MOV A,C ;LIMIT SELECT TO REAL OPTIONS
CPI MAXDSK ;
JRNC SELERR
MVI B,0
LXI H,SEL0
DAD B
MOV A,M
ORA A
JRZ SELERR
MOV A,C
CPI 4
JRNC CHKHRD
MOV A,M
OUT 08H
PUSH B
MVI C,1
CALL DELAY
POP B
IN 04H
RAL
JRC SELERR
JR SELSDT
CHKHRD:
MOV A,M
OUT 20H
PUSH B
MVI C,1
CALL DELAY
POP B
IN 24H
RAL
JRNZ SELERR
SELSDT:
LXI H,0
mov a,c
STA NEWDSK ;SAVE FOR I/O LATER
MOV L,C ;COMPUTE DP HEADER ADDRESS
DAD H ;* 2
DAD H ;* 4
DAD H ;* 8
DAD H ;* 16 (DP HEADER SIZE)
LXI D,DPBASE ;START OF DP HEADERS
DAD D ;POINT TO CORRECT ONE
SHLD DPEPTR ;SAVE ADDRESS OF CURRENT DP BLOCK
RET ;
SELERR:
LXI H,0
RET
SETDMA:
MOV H,B ;TO ALLOW SAVING
MOV L,C ;
SHLD DMAADR ;
RET ;RETURN TO CALLER
SETTRK:
MOV H,B ;TO ALLOW SAVE
MOV L,C ;
SHLD NEWTRK ;SAVE NEXT TRACK NUMBER
RET ;RETURN TO CALLER
SETSEC:
MOV A,C ;FOR SAVE
STA NEWSEC ;
RET ;RETURN TO CALLER
SETDEN:
LXI D,SEL0 ;START OF SELECT/DENSITY MASKS
LHLD NEWDSK ;NEXT DRIVE ADDRESS
MVI H,000H ;ENSURE ZERO FOR SINGLE BYTE QUANTITY
DAD D ;POINT TO CORRECT MASK
MOV A,C ;ISOLATE DENSITY BIT
ANI 00000001B ;
MOV C,A ;SAVE FOR NOW
MOV A,M ;LOAD SELECT DENSITY MASK
ANI 11111110B ;RESET CURRENT DENSITY SETTING
ORA C ;SET NEW VALUE
MOV M,A ;RESTORE MASK IN TABLE
RET ;RETURN TO CALLER
READ:
CALL RETMOD ;WHAT TYPE OF I/O ??
CPI 003H ;
JC READSOFT ;FLOPPY DISK DRIVE....
JMP READHARD ;HARD DISK I/O
WRITE:
CALL RETMOD ;WHAT TYPE OF I/O ??
CPI 003H ;
JC WRITESOFT ;FLOPPY DISK
JMP WRITEHARD ;HARD DISK I/O
PAGE
;-----------------------------------------------------------------------
;
; ROUTINES TO SET AND RETURN THE CURRENT DRIVE MODE
;
;-----------------------------------------------------------------------
SETMOD:
LHLD NEWDSK ;NEXT DRIVE FOR I/O
MVI H,000H ;
MOV A,L ;CHECK MODE SET VALIDITY
CPI 004H ;ONLY VALID FOR FLOPPY DISK DRIVES
RNC ;INVALID DRIVE FOR MODE SET, RETURN
LXI D,MODE ;START OF MODE BYTES
DAD D ;
MOV M,C ;SAVE NEW MODE BYTE
PUSH H ;SAVE MODE BYTE ADDRESS
MOV A,C ;SETUP FOR DENSITY CHANGE
ORA A ;
MVI C,000H ;ASSUME SINGLE DENSITY MODE....
JRZ SETSEL ;VERIFY ASSUMPTION
MVI C,001H ;SET FOR DOUBLE DENSITY MODE....
SETSEL: CALL SETDEN ;SET DENSITY BASED ON LOW BIT
POP H ;RESTORE
MOV L,M ;PICKUP MODE AGAIN
MVI H,000H ;FOR SINGLE BYTE PRECISION
MOV A,L ;SAVE MODE IN ACCUMULATOR FOR LATER
DAD H ;* 2
DAD H ;* 4
PUSH H ;SAVE * 4
DAD H ;* 8
POP D ;REGAIN * 4
DAD D ;* 12
LXI D,MODL0 ;FIRST MODEL DPE
DAD D ;POINT TO THIS ONE
XCHG ;SETUP TEMPORARILY AS DESTINATION
LHLD DPEPTR ;ADDRESS OF CURRENTLY SELECTED DPE
XCHG ;SETUP TO ALTER
LXI B,12 ;LENGTH FOR MOVE
LDIR ;DO MOVE
RET ;RETURN TO CALLER
RETMOD:
LXI D,MODE ;START OF MODE BYTES
LHLD NEWDSK ;NEXT DRIVE FOR I/O
MVI H,000H ;RESET FOR SINGLE BYTE QUANTITY
DAD D ;POINT TO IT....
MOV A,M ;LOAD IT FOR CALLER
RET ;RETURN, WITH CURRENT MODE SETTING
PAGE
;-----------------------------------------------------------------------
;
; THIS IS THE HOME DEVICE ROUTINE
;
;-----------------------------------------------------------------------
HOMEIT: LDA NEWDSK ; CHECK FOR FIRST HOME
CPI 4 ; CHECK FOR FLOPPY
JC HOME ; DO NOT BYPASS FLOPPY HOME
MOV C,A ;
MVI B,0 ; POINT TO PRESENT TRACK STORED
LXI H,TRK0 ;
DAD B ;
MOV A,M ; CHECK IF INITIALIZED
CPI 0FFH ;
MVI A,0 ;
RNZ ; YES - RETURN WITH NO ERROR
MOV M,A ;
HOME:
LDA NEWDSK ;GET VALUE OF DRIVE FOR HOME
CPI 004H ;IS IT A HARD DISK ??
JNC HOMEHARD ;YES, PROCESS....
HOMESOFT:
CALL DSKSEL ;SELECT CORRECT DRIVE (IN ACCUMULATOR)
CALL POINT ;POINT TO TRACK REGISTER SAVE AREA
MVI M,000H ;RESET TO TRACK ZERO
CALL DBL$UPDATE ;
MVI A,00AH ;HOME COMMAND....
OUT 004H ;DO IT....
HOME1: CALL WAIT0 ;WAIT UNTIL I/O COMPLETE
LDA STATUS ;PICKUP STATUS BYTE
ANI 10011000B ;CHECK STATUS
RZ ;RETURN WITH GOOD ESULT
MVI A,001H ;SET ERROR ON HOME
RET ;AND RETURN....
HOMEHARD:
IF HARDSK
CALL DSKSEL ;SELECT CORRECT DRIVE (IN ACCUMULATOR)
CALL POINT ;POINT TO SAVE AREA
MVI M,000H ;SET TO TRACK ZERO
XCHG ;POINT TO SELECT WORD
MOV A,M ;LOAD SELECT MASK
ANI 11110000B ;RESET HEAD MASK
MOV M,A ;SAVE
OUT 020H ;WRITE HEAD/SELECT MASK
MVI A,020H ;HOME COMMAND
OUT 023H ;DO IT....
HOME2: CALL WAIT0 ;WAIT UNTIL I/O COMPLETE
MVI C,20 ;DELAY FOR 20 MILLISECONDS
CALL DELAY ;
XRA A ;SET NEW TRACK REGISTER TO ZERO
OUT 022H ;FOR CONTROLLER
; LXI H,MHM ;***DEBUG***
; CALL MSPRT ;***DEBUG***
LDA STATUS ;PICKUP STATUS BYTE
ANI 01011101B ;CHECK STATUS
RZ ;
MVI A,001H ;SET ERROR ON HOME
ENDIF
RET ;AND RETURN
PAGE
;-----------------------------------------------------------------------
;
; THESE ARE THE HARD DISK UNBLOCK/REBLOCK AND READ AND WRITE
; ROUTINES CALLED BY THE BDOS SOFTWARE.
;
;-----------------------------------------------------------------------
READHARD:
IF HARDSK
XRA A ;RESET UNALLOCATED COUNT
STA UNACNT ;
MVI A,001H ;READ THE SELECTED CP/M SECTOR
STA READOP ;
STA RSFLAG ;MUST READ DATA
MVI A,WRUAL ;
STA WRTYPE ;TREAT AS UNALLOCATED
JMP RWOPER ;TO PERFORM THE READ
ENDIF
WRITEHARD:
IF HARDSK
XRA A ;WRITE THE SELECTED CP/M SECTOR
STA READOP ;NOT A READ OPERATION
MOV A,C ;WRITE TYPE IS PASSED IN REG C
STA WRTYPE ;
CPI WRUAL ;IS IT WRITE UNALLOCATED ??
JRNZ CHKUNA ;CHECK FOR UNALLOCATED
;
; WRITE TO UNALLOCATED, SET PARAMETERS
;
MVI A,BLKSIZ/128 ;NEXT UNALLOC RECS
STA UNACNT ;
LDA NEWDSK ;DISK FOR I/O
STA UNADSK ;UNADSK = NEWDSK
LHLD NEWTRK ;
SHLD UNATRK ;UNATRK = NEWTRK
LDA NEWSEC ;
STA UNASEC ;UNASEC = NEWSEC
;
; CHECK FOR WRITE TO UNALLOCATED SECTOR
;
CHKUNA:
LDA UNACNT ;ANY UNALLOCATED REMAIN ??
ORA A ;
JZ ALLOC ;SKIP IS NOT
;
; MORE UNALLOCATED RECORDS REMAIN
;
DCR A ;UNACNT = UNACNT - 1
STA UNACNT ;
LDA NEWDSK ;SAME DISK ??
LXI H,UNADSK ;
CMP M ;NEWDSK = UNADSK ??
JNZ ALLOC ;SKIP IF NOT
;
; DISKS ARE THE SAME
;
LXI H,UNATRK ;
CALL NEWTRKCMP ;NEWTRK = UNATRK ??
JNZ ALLOC ;SKIP IF NOT
;
; TRACKS ARE THE SAME
;
LDA NEWSEC ;SAME SECTOR ??
LXI H,UNASEC ;
CMP M ;NEWSEC = UNASEC ??
JRNZ ALLOC ;SKIP IF NOT
;
; MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE
;
INR M ;UNASEC = UNASEC + 1
MOV A,M ;END OF TRACK ??
CPI CPMSPT ;COUNT CP/M SECTORS
JRC NOOVF ;SKIP IF NO OVERFLOW
;
; OVERFLOW TO NEXT TRACK
;
MVI M,000H ;UNASEC = 0
LHLD UNATRK ;
INX H ;
SHLD UNATRK ;UNATRK = UNATRK + 1
;
; MATCH FOUND, MARK AS UNNECESSARY READ
;
NOOVF:
XRA A ;ZERO TO ACCUMULATOR
STA RSFLAG ;RSFLAG = 0
JR RWOPER ;TO PERFORM THE WRITE
;
; NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
;
ALLOC:
XRA A ;ZERO TO ACCUMULATOR
STA UNACNT ;UNACNT = 0
INR A ;ONE TO ACCUMULATOR
STA RSFLAG ;RSFLAG = 1
;-----------------------------------------------------------------------
;
; THE FOLLOWING CODE IS COMMON TO BOTH READ AND WRITE
;
;-----------------------------------------------------------------------
RWOPER:
XRA A ;ZERO TO ACCUMULATOR
STA ERFLAG ;NO ERRORS YET....
LDA NEWSEC ;COMPUTE HOST SECTOR
REPT SECSHF ;COMPUTE HOST SECTOR
ORA A ;CARRY = 0
RAR ;SHIFT RIGHT
ENDM
STA NEWHST ;HOST SECTOR TO SEEK
;
; ACTIVE HOST SECTOR ??
;
LXI H,HSTACT ;HOST ACTIVE FLAG
MOV A,M ;
MVI M,001H ;ALWAYS BECOMES 1
ORA A ;WAS IT ALREADY ??
JZ FILLHST ;FILL HOST IF NOT
;
; HOST BUFFER ACTIVE, SAME AS SEEK BUFFER
;
LDA NEWDSK ;
LXI H,HSTDSK ;SAME DISK ??
CMP M ;NEWDSK = HSTDSK ??
JNZ NOMATCH ;
;
; SAME DISK, SAME TRACK ??
;
LXI H,HSTTRK ;
CALL NEWTRKCMP ;NEWTRK = HSTTRK ??
JRNZ NOMATCH ;
;
; SAME DISK, SAME TRACK, SAME BUFFER ??
;
LDA NEWHST ;
LXI H,HSTSEC ;NEWHST = HSTSEC ??
CMP M ;
JZ MATCH ;SKIP IF MATCH
;
; PROPER DISK, BUT NOT CORRECT SECTOR
;
NOMATCH:
LDA HSTWRT ;HOST WRITTEN ??
ORA A ;
CNZ WRITEHST ;CLEAR HOST BUFFER
;
; MAY HAVE TO FILL HOST BUFFER
;
FILLHST:
LDA NEWDSK ;
STA HSTDSK ;
LHLD NEWTRK ;
SHLD HSTTRK ;
LDA NEWHST ;
STA HSTSEC ;
LDA RSFLAG ;NEED TO READ ??
ORA A ;
CNZ READHST ;YES, IF 1
XRA A ;ZERO TO ACCUMULATOR
STA HSTWRT ;NO PENDING WRITE
MATCH:
LDA NEWSEC ;MASK BUFFER NUMBER
ANI SECMSK ;LEAST SIGNIF BITS
MOV L,A ;READY TO SHIFT
MVI H,000H ;DOUBLE COUNT
REPT 7
DAD H ;
ENDM
;
; HL NOW HAS RELATIVE HOST BUFFER ADDRESS
;
LXI D,HSTBUF ;
DAD D ;HL = HOST ADDRESS
XCHG ;NOW IN DE
LHLD DMAADR ;GET/PUT CP/M DATA
XCHG ;SET FOR Z80 LDIR INSTRUCTION
LXI B,128 ;LENGTH OF MOVE
LDA READOP ;WHICH WAY ??
ORA A ;
JRNZ RWMOVE ;SKIP IF READ
;
; WRITE OPERATION, MARK AND SWITCH DIRECTION
;
MVI A,001H ;
STA HSTWRT ;HSTWRT = 1
XCHG ;SWAP DIRECTION
;
; MOVE SUBROUTINE
;
RWMOVE:
LDIR ;MOVE DATA TO/FROM BUFFER
;
; DATA HAS BEEN MOVED TO/FROM HOST BUFFER
;
LDA WRTYPE ;WRITE TYPE ??
CPI WRDIR ;TO DIRECTORY ??
JRNZ RWEND ;NO, JUST END UP HERE
;
; CLEAR HOST BUFFER FOR DIRECTORY WRITE
;
LDA ERFLAG ;CHECK PRIOR TO DIR ACTIVITY
ORA A ;ERRORS ??
JRNZ RWEND ;SKIP IF SO....
XRA A ;ZERO TO ACCUMULATOR
STA HSTWRT ;BUFFER WRITTEN
CALL WRITEHST ;
RWEND:
LDA ERFLAG ;
ORA A ;IF ERRORS, RESET SO NO MATCH NEXT TIME THRU
RZ ;NONE, JUST RETURN
LXI H,HSTDSK ;
MVI M,0FFH ;CANT POSSIBLY MATCH, MUST REDO I/O
ENDIF
RET ;
MVDTB: LHLD DMAADR ; MOVE DATA TO FLOPPY BUFFER
LXI D,FPYBUF ;
LXI B,128 ; 128 BYTES
LDIR ;
RET ;
MVDFB: PUSH PSW ; MOVE DATA FROM FLOPPY BUFFER
LDA CMD ;
ANI 20H ; CHECK FOR READ
JNZ MVDFX ; NO - BYPAS MOVE
LHLD DMAADR ;
XCHG ; DE = DESTINATION
LXI H,FPYBUF ;
LXI B,128 ; 128 BYTES
LDIR ;
MVDFX: POP PSW ;
RET ;
PAGE
;-----------------------------------------------------------------------
;
; UTILITY SUBROUTINE FOR 16 BIT COMPARE
;
;-----------------------------------------------------------------------
IF HARDSK
NEWTRKCMP:
XCHG ;HL = .UNATRK OR .HSTTRK
LXI H,NEWTRK ;
LDAX D ;LOW BYTE COMPARE
CMP M ;SAME ??
RNZ ;RETURN IF NOT
INX D ;TO CHECK HIGH BYTE
INX H ;
LDAX D ;
CMP M ;SETS FLAGS
RET ;
PAGE
;-----------------------------------------------------------------------
;
; WRITEHST PERFORMS THE PHYSICAL WRITE TO THE HOST DISK.
; READHST PERFORMS THE PHYSICAL READ FROM THE HOST DISK.
;
; HSTDSK = HOST DISK NUMBER
; HSTTRK = HOST TRACK NUMBER
; HSTSEC = HOST SECTOR NUMBER
; RETURN ERROR FLAG IN ERFLAG
;
;-----------------------------------------------------------------------
WRITEHST:
MVI A,005H ;SETUP DMA FOR WRITE
STA DMAS3F ;
MVI A,002H ;WRITE COMMAND
STA CMD ;SAVE FOR LATER
LXI H,HSTBUF-1 ;WRITE MUST WRITE CONTROL BYTE
SHLD DMASA ;
JMP HRW0 ;
READHST:
MVI A,001H ;SETUP DMA FOR READ
STA DMAS3F ;
MVI A,004H ;READ COMMAND
STA CMD ;SAVE FOR LATER
LXI H,HSTBUF ;READ ONLY DATA BYTES
SHLD DMASA ;
HRW0:
LXI H,T$RETRIES ;SETUP TEMPORARY RETRIES COUNT
MVI M,003H ;
HRW1:
LDA HSTSEC ;HOST SECTOR NUMBER
STA SECTNO ;SAVE SECTOR NUMBER
LDA HSTDSK ;PICKUP DRIVE ID FOR SELECT
CALL DSKSEL ;SELECT CORRECT DRIVE FOR I/O
CALL POINT ;POINT TO TRACK REGISTER SAVE AREA
XCHG ;POINT TO SELECT MASK
MVI A,11110000B ;TO REMOVE CURRENT HEAD SELECTION
ANA M ;
MOV M,A ;
PUSH H ;SAVE MASK ADDRESS
CALL SETHED ;COMPUTE CORRECT HEAD NUMBER
MOV A,L ;TRACK NUMBER AFTER HEAD CALCULATION
STA TRAKNO ;
POP H ;RESTORE MASK ADDRESS
LDA HEADNO ;TO OR IN NEW HEAD NUMBER
ORA M ;
MOV M,A ;SAVE NEW DRIVE/HEAD SELECTION
ANI 07FH ; MASK OFF LARGE DRIVE FLAG
OUT 020H ;WRITE IT TO SELECT NEW HEAD....
MVI C,1 ;DELAY FOR 1 MILLISECOND
CALL DELAY ;
HRW2:
CALL POINT ;IS A SEEK NECESSARY ??
LDA TRAKNO ;CHECK
CMP M ;WELL ??
JZ HRW5 ;NO SEEK NECESSARY...
HRW3:
OUT 022H ;WRITE NEW TRACK NUMBER
MOV B,M ;SAVE TEMPORARILY
MOV M,A ;UPDATE TRACK REGISTER SAVE AREA
MOV A,B ;OLD TRACK NUMBER
OUT 021H ;TO OLD TRACK REGISTER
MVI A,010H ;SEEK COMMAND
OUT 023H ;DO IT....
HRW4: CALL WAIT0 ;WAIT FOR I/O
MVI C,20 ;DELAY AFTER SEEK FOR 20 MILLISECONDS
CALL DELAY ;
HRW5:
LDA SECTNO ;SET SECTOR
OUT 021H ;
HRW6:
LXI H,DMAS1 ;SETUP DMA FOR HARD DISK I/O
LXI B,0600H ;
OUTIR ;
LXI H,DMAS2H ;
LXI B,0600H ;
OUTIR ;
LXI H,DMAS3 ;
LXI B,0700H ;
OUTIR ;
LDA CMD ;PICKUP I/O COMMAND
OUT 023H ;WRITE IT OUT
HRW7: CALL WAIT0 ;WAIT FOR COMPLETION
MVI A,01011101B ;SETUP STATUS AND MASK
STA MASK ;SAVE FOR STATUS CHECK
CALL CHECK$STAT ;CHECK STATUS FROM I/O
RZ ;OK ??
JMP HRW1 ;RETRY I/O
ENDIF
PAGE
;-----------------------------------------------------------------------
;
; DOUBLE SIDED TRACK REGISTER UPDATE ROUTINE
;
;-----------------------------------------------------------------------
DBL$UPDATE:
LDA MPARMS ;CHECK FOR DOUBLE SIDED DRIVES
ANI 1 ; IS FLAG SET
RZ ; NO - SO RETURN
LDA DISKNO ;CURRENT DISK DRIVE
CPI 004H ;IS IT A FLOPPY
RNC ;NO, RETURN WITHOUT UPDATE
ANI 00000010B ;IS THIS DRIVE 2 0R 3 ??
MOV A,M ;WE WERE CALLED WITH (HL) POINTING TO TRACK
JRZ DBL$LOW ;IT MUST BE DRIVE ZERO OR ONE
DCX H ;BACKUP TO OTHER SIDE POINTER
DCX H ;
JR DBL$SAVE ;
DBL$LOW:
INX H ;BUMP UP TO DRIVE TWO OR THREE
INX H ;
DBL$SAVE:
MOV M,A ;UPDATE OTHER SIDE REGISTER
RET ;
PAGE
;-----------------------------------------------------------------------
;
; ROUTINE TO COMPUTE HEAD NUMBER FROM TRACK NUMBER
; TRACK NUMBER IS IN HL ON ENTRY
;
;-----------------------------------------------------------------------
IF HARDSK
SETHED:
LHLD HSTTRK ;CP/M TRACK NUMBER (0-800)
ANI 80H ; CHECK FOR LARGE DRIVE
MOV A,L ;LOW ORDER
JRZ SETH14 ; SMALL DRIVE
ANI 00000111B ;GET TRACK MOD 8 (HEAD NUMBER)
MVI C,3 ;LIMIT LOOP FOR DIVIDE BY EIGHT
JR SETDVD ;
SETH14: ANI 00000011B ;GET TRACK MOD 4 (HEAD NUMBER)
MVI C,2 ;LIMIT LOOP FOR DIVIDE BY FOUR
SETDVD: STA HEADNO ;SAVE AS HEAD NUMBER
SHD1: ORA A ;ENSURE CARRY IS ZERO
MOV A,H ;FOR SHIFT
RAR ;ONE BIT
MOV H,A ;
MOV A,L ;LOW ORDER
RAR ;CARRY PARTICIPATES FROM HIGH ORDER
MOV L,A ;
DCR C ;END OF DIVIDE YET ??
JRNZ SHD1 ;NO, CONTINUE
RET ;RETURN TO CALLER, TRACK IN HL
ENDIF
PAGE
;-----------------------------------------------------------------------
;
; DISK DRIVE SELECT ROUTINE
; ON ENTRY, THE ACCUMULATOR CONTAINS THE DRIVE FOR SELECTION
; RETURNS CARRY SET FOR HARD DISK SELECTED
; RETURNS CARRY RESET FOR FLOPPY DISK SELECTED
;
;-----------------------------------------------------------------------
DSKSEL:
CPI 004H ;IS IT HARD DISK ??
JNC SELHARD ;YES, GO PROCESS....
SELSOFT:
LXI H,DISKNO ;CURRENT DRIVE NUMBER
CMP M ;SAME DRIVE AS LAST TIME ??
JRZ SLS3 ;YES, DONT BOTHER WITH UNLOAD
MOV M,A ;UPDATE WITH CURRENT DRIVE NUMBER
;-----------------------------------------------------------------------
;
; WE WILL NOW FORCE THE HEAD TO UNLOAD PRIOR TO THE SWITCH
; TO ENSURE THAT WHEN WE RETURN TO THIS DISK WE WILL
; LOAD AND WAIT FOR THE HEAD TO SETTLE.
;
;-----------------------------------------------------------------------
SLS1:
IN 004H ;ENSURE FLOPPY PORT NOT BUSY
RAR ;
JRC SLS1 ;
IN 005H ;READ THE TRACK REGISTER
OUT 007H ;ENSURE WE DONT MOVE THE HEAD
MVI A,012H ;SEEK AND UNLOAD HEAD
OUT 004H ;DO IT....
SLS2: CALL WAIT0 ;WAIT HERE FOR INTERRUPT
;-----------------------------------------------------------------------
;
; WE WILL NOW LOAD THE SELECT MASK AND SELECT THE DRIVE
; EVEN IF ITS THE SAME DRIVE BECAUSE THE DENSITY MAY
; HAVE CHANGED.
;
;-----------------------------------------------------------------------
SLS3:
CALL POINT ;POINT TO TRACK SAVE AREA
XCHG ;POINT TO SELECT MASK
LDA TRAKNO ;NEXT TRACK FOR I/O
CPI 002H ;IS IT TRACK ZERO OR ONE
MVI A,11111111B ;ASSUME NO....
JRNC SLS4 ;VERIFY ASSUMPTION
MVI A,11111110B ;FORCE SINGLE DENSITY FOR 0, & 1
SLS4:
ANA M ;LOAD MASK AND CORRECT IF NECESSARY
OUT 008H ;SELECT IT
XCHG ;RESTORE TRACK REGISTER ADDRESS
MOV A,M ;PICK UP TRACK NUMBER
OUT 005H ;GIVE IT TO CONTROLLER
ORA A ;ENSURE CARRY IS RESET
RET
;-----------------------------------------------------------------------
;
; THIS ROUTINE SETS UP THE HARD DISK BY SELECTING THE CORRECT
; DRIVE AND RELOADING THE HEAD AND TRACK REGISTERS IN THE
; HARD DISK CONTROLLER READY FOR I/O LATER.
;
;-----------------------------------------------------------------------
SELHARD:
IF HARDSK
LXI H,DISKNO ;CURRENT DRIVE SELECTED
CMP M ;SAME ??
RZ ;YES, NO NEW SELECT NECESSARY
MOV M,A ;UPDATE DISKNO
SLH1:
CALL POINT ;TRACK SAVE REGISTER
XCHG ;POINT TO SELECT MASK
MOV A,M ;LOAD DRIVE/HEAD VALUE
OUT 020H ;WRITE IT TO SELECT PORT
XCHG ;REGAIN ADDRESS OF TRACK REGISTER
MOV A,M ;LOAD OLD TRACK NUMBER
OUT 022H ;WRITE IT TO OLD TRACK REGISTER
MVI C,20 ;DELAY FOR 20 MILLISECONDS AFTER SELECT
CALL DELAY ;
STC ;SET CARRY TO SHOW HARD DISK
ENDIF
RET ;RETURN TO CALLER
PAGE
;-----------------------------------------------------------------------
;
; SUBROUTINE TO POINT TO CURRENT TRACK REGISTER SAVE AREA
;
;-----------------------------------------------------------------------
POINT:
LHLD DISKNO ;PICKUP CURRENT DISK
MOV A,L ;
MVI H,0 ;RESET HIGH ORDER HALF
LXI D,TRK0 ;LOAD TRACK POINTER
DAD D ;POINT TO CURRENT TRACK PTR
MOV D,H ; DE = TRACK
MOV E,L ;
LXI B,12 ;
DAD B ; HL = SELECT
IF HARDSK
CPI 4 ;
JRC PNTFN ; FLOPPY DISK
MVI A,10H ;
ANA M ; CHECK DRIVE SELECT
JRZ PNTH2 ; MUST BE DRIVE # 2
LXI D,HTK1 ; POINT TO DRIVE 1
JR PNTFN ;
PNTH2: LXI D,HTK2 ; POINT TO DRIVE 2
ENDIF
PNTFN: XCHG ; SWITCH
RET ; HL = TRACK DE = SELECT
;-----------------------------------------------------------------------
;
; ROUTINE TO TRANSLATE SECTOR NUMBER
;
;-----------------------------------------------------------------------
SECTRAN:
XCHG ;TABLE ADDRESS IS IN DE (NOW HL)
MOV A,H ;IS THERE A TABLE ADDRESS ??
ORA L ;
JRZ STRN2 ;NO, JUST RETURN ENTERED QUANTITY
STRN1:
MVI B,000H ;ENSURE OK FOR SINGLE BYTE QUANTITY
DAD B ;ADD SECTOR NUMBER
MOV L,M ;LOAD TRANSLATED VALUE
MVI H,000H ;
RET ;NEW VALUE RETURNED IN HL
STRN2:
DAD B ;RETURN SAME VALUE AS ENTERED
RET ;
;-----------------------------------------------------------------------
;
; ROUTINES TO DO FLOPPY I/O
;
;-----------------------------------------------------------------------
READSOFT:
MVI A,09FH ;MASK FOR READ STATUS
STA MASK ;
MVI A,001H ;SETUP DMA FOR READ
STA DMAS3F ;
MVI A,08CH ;READ COMMAND
JR SRW1 ;
WRITESOFT:
MVI A,0FFH ;MASK FOR WRITE STATUS
STA MASK ;
CALL MVDTB ;
MVI A,005H ;SETUP DMA FOR WRITE
STA DMAS3F ;
MVI A,0ACH ;WRITE COMMAND
SRW1:
STA CMD ;
LXI H,FPYBUF ;
SHLD DMASA ;
LDA NEWDSK ;
CALL DSKSEL ;SELECT DRIVE FOR I/O
SRW2:
MVI A,003H ;SET NUMBER OF TRIALS
STA T$RETRIES ;SAVE FOR RETRY ROUTINE
LOAD$HEAD:
IN 008H ;IS HEAD LOADED ??
ANI 00000010B ;CHECK IT....
JNZ REMOVE$LD ;YES, ITS LOADED, DONT RELOAD....
IN 005H ;DUMMY SEEK TO START HEAD LOADING
OUT 007H ;KEEP IT SHORT....
MVI A,01AH ;START HEAD LOADING
OUT 004H ;
LDH1: CALL WAIT0 ;WAIT FOR I/O TO COMPLETE
MVI C,16 ;WAIT HERE FOR 16 MS
CALL DELAY ;CALL WAIT ROUTINE
CALL POINT ;REESTABLISH TRACK REGISTER POINTER
MVI M,254 ;ENSURE FURTHER SEEK AND DELAY....
JR TRKTST ;
REMOVE$LD:
LXI H,CMD ;POINT TO I/O COMMAND
MVI A,11111011B ;REMOVE HEAD LOAD BIT
ANA M ;DO IT....
MOV M,A ;SAVE IT BACK INTO CMD
TRKTST:
CALL POINT ;RESTORE TRACK REGISTER POINTER
LDA NEWTRK ;GET NEW TRACK NUMBER
STA TRAKNO ;SAVE IN COMMON PLACE
CMP M ;SAME AS LAST TIME ??
JRZ FSECSET ;YES, DONT BOTHER WITH SEEK
MOV M,A ;SAVE IT
OUT 007H ;ALSO SEND IT TO CONTROLLER
CALL DBL$UPDATE ;DOUBLE SIDED SUPPORT
FLOPPY$SEEK:
MVI A,01AH ;SEEK COMMAND WITH HEAD LOAD
OUT 004H ;DO IT....
FPS1: CALL WAIT0 ;WAIT FOR I/O TO COMPLETE
MVI C,16 ;SET FOR 16 MS DELAY
CALL DELAY ;
FSECSET:
LDA NEWSEC ;SET SECTOR
STA SECTNO ;SAVE IN COMMONN PLACE
OUT 006H ;
CALL FLOPPYIO ;DO I/O
CALL CHECK$STAT ;CHECK STATUS OF I/O
LDA ERFLAG ;SETUP TO RETURN TO BDOS
CZ MVDFB ;
RZ ;EITHER OK OR PERMANENT ERROR
JMP LOAD$HEAD ;ERROR, JUST RETRY THIS SAME I/O
PAGE
;-----------------------------------------------------------------------
;
; THIS IS THE ROUTINE THAT DOES THE FLOPPY DISK I/O
;
;-----------------------------------------------------------------------
FLOPPYIO:
IF NOT DMA
LXI H,066H ;MOVE DATA FROM 066H TO SAVE
LXI D,SAVE1 ;
LXI B,004H ;
LDIR ;MOVE IT
LXI H,NMIRTN ;SET NMI ROUTINE TO NMI ADDRESS
LXI D,066H ;
LXI B,004H ;
LDIR ;MOVE IT
LDA CMD ;IS IT A WRITE ??
ANI 20H ;
JZ FRD ;NO, LEAVE INI CMD IN LOW MEMORY
LXI H,067H ;POINT TO COMMAND AREA
MVI M,0A3H ;MAKE IT AN OTI CMD....
FRD EQU $ ;LABEL
ENDIF
IF DMA
LXI H,DMAS1 ;INITIALIZE DMA
LXI B,0600H ;
OUTIR ;WRITE TO DMA
LXI H,DMAS2F ;
LXI B,0400H ;
OUTIR ;WRITE TO DMA
LXI H,DMAS3 ;
LXI B,0700H ;
OUTIR ;WRITE TO DMA
ENDIF
MVI C,007H ;PORT ADDRESS FOR I/O
LXI H,FPYBUF ;DMA ADDRESS
LDA CMD ;I/O COMMAND
OUT 004H ;WRITE TO DISK CONTROLLER
FWT1: CALL WAIT0 ;WAIT HERE FOR I/O TO COMPLETE
IF NOT DMA
LXI H,SAVE1 ;SETUP TO REPLACE DATA
LXI D,066H ;COPIED FROM NMI LOCATION
LXI B,004H ;
LDIR ;MOVE IT....
ENDIF
RET ;RETURN, I/O COMPLETED
;-----------------------------------------------------------------------
;
; WE WILL NOW CHECK THE STATUS OF THE I/O OPERATION
; RETURN WITH CONDITION CODE ZERO = NO RETRY
; RETURN WITH CONDITION CODE NON ZERO = RETRY
;
;-----------------------------------------------------------------------
CHECK$STAT:
LXI H,ERFLAG ;POINT TO ERROR INDICATOR
MVI M,000H ;ASSUME OK
LXI H,STATUS ;CHECK STATUS
LDA MASK ;MASK FOR UNWANTED BIT REMOVAL
ANA M ;
MOV M,A ;SAVE CLEANED STATUS
RZ ;OK, SO RETURN
CHKS0:
CALL RETMOD ;
CPI 003H ;HARD DISK ??
LXI H,STATUS ;
MOV A,M ;RELOAD STATUS BYTE
JRNC CHKS2 ;YES, CHECK FOR DRIVE READY
CHKS1:
CPI 080H ;IS FLOPPY DISK NOT READY ???
JZ BADIO ;YES, DONT BOTHER WITH RETRY OR MESSAGE
JR CHKS3 ;GO TO BAD MESSAGE ROUTINE
CHKS2:
CPI 000H ;IS HARD DISK NOT READY ??
JZ BADIO ;YES, BYPASS ERROR MESSAGE AND COUNTING
ANI 01000000B ;IS IT WRITE FAULT ??
JRZ CHKS3 ;NO, CONTINUE ON
CALL POINT ;POINT TO TRACK REGISTER
XCHG ;POINT TO SELECT MASK
MOV A,M ;
ORI 01000000B ;TURN ON WRITE FAULT CLEAR
OUT 020H ;
MOV A,M ;RESET CLEAR
OUT 020H ;
MVI C,20 ;DELAY JUST TO BE SAFE
CALL DELAY ;
CHKS3:
LDA STATUS ;SAVE STATUS OVER HOME
PUSH PSW ;
CALL HOME ;RESET DEVICE TO HOME
POP PSW ;
STA STATUS ;SAVE FOR ERROR MESSAGE
LXI D,TCNT ;BUMP TEMP ERROR COUNT
CALL ADDERRORS ;
LXI H,T$RETRIES ;PICKUP RETRY COUNT
DCR M ;DECREMENT COUNT OF RETRIES
RNZ ;
LXI D,PCNT ;BUMP PERMANENT ERROR COUNT
CALL ADDERRORS ;
BADIO:
LXI H,ERFLAG ;SET PERMANENT ERROR
MVI M,001H ;DO IT....
XRA A ;RESET TO PRECLUDE RETRIES
RET ;RETURN TO CALLER
ADDERRORS:
LHLD DISKNO ;BUMP COUNT OF DISK ERRORS
MVI H,000H ;
DAD D ;POINT TO ERROR REGISTER
INR M ;
RET ;
PAGE
;-----------------------------------------------------------------------
;
; CENTRONICS PRINTER ROUTINE (WITH SEPARATE BUSY TEST FOR SPOOLER)
;
;-----------------------------------------------------------------------
CNSTAT:
MVI A,001H ;TO SET STROBE HIGH
OUT 010H ;
IN 010H ;READ PRINTER STATUS
ANI 020H ;REMOVE ALL BUT BUSY BIT
MVI A,0FFH ;ASSUME NOT BUSY
RZ ;CHECK ASSUMPTION
XRA A ;SET TO SHOW STILL BUSY
RET ;
;
; WE WILL NOW PERFORM THE PRINT FUNCTION BUSY TEST
;
CNTBSY:
CALL CNSTAT ;CHECK STATUS OF PRINTER
CPI 0FFH ;READY ??
JRNZ CNTBSY ;NO, WAIT HERE
RET ;
CLIST:
CALL CNTBSY ;WAIT FOR PRINTER TO FREE UP
MOV A,C ;CHARACTER TO PRINT
OUT 011H ;WRITE IT TO DATA PORT
MVI A,000H ;TO FORCE STROBE LOW
OUT 010H ;
MVI A,001H ;TO FORCE STROBE HIGH
OUT 010H ;
RET ;
PAGE
;-----------------------------------------------------------------------
;
; DISK INTERRUPT ROUTINE
;
;-----------------------------------------------------------------------
FLOPPY$INT:
SHLD SVDHL
LXI H,FDINTH
JMP INTINIT
FDINTH:
IN 004H ;GET STATUS
STA STATUS ;SAVE FOR I/O ROUTINE
JMP HDSTFLG
HARD$INT:
SHLD SVDHL
LXI H,HDINTH
JMP INTINIT
HDINTH:
IN 024H ;GET STATUS
STA STATUS ;SAVE FOR CHECK LATER
XRA A ;TO RESET INTERRUPT PENDING BIT
OUT 023H ;RESET BY RELOADING THE COMMAND REGISTER
HDSTFLG:
MVI C,FLAGST
MVI E,5
CALL XDOS
JMP INTDONE
PAGE
;-----------------------------------------------------------------------
;
; CONSOLE DISPLAY ROUTINES
;
;-----------------------------------------------------------------------
;
CONST: ; CONSOLE STATUS
CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR
DW PT0ST ; CONSOLE #0 STATUS ROUTINE
DW PT1ST ; CONSOLE #1 STATUS ROUTINE
DW PT2ST ; CONSOLE #2 STATUS ROUTINE
DW PT3ST ; CONSOLE #3 STATUS ROUTINE
CONIN: ; CONSOLE INPUT
CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR
DW PT0IN ; CONSOLE #0 INPUT
DW PT1IN ; CONSOLE #1 INPUT
DW PT2IN ; CONSOLE #2 INPUT
DW PT3IN ; CONSOLE #3 INPUT
CONOUT: ; CONSOLE OUTPUT
CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR
DW PT0OUT ; CONSOLE #0 OUTPUT
DW PT1OUT ; CONSOLE #1 OUTPUT
DW PT2OUT ; CONSOLE #2 OUTPUT
DW PT3OUT ; CONSOLE #3 OUTPUT
;
PTBLJMP: ; COMPUTE AND JUMP TO HANDLER
; D = CONSOLE #
; DO NOT DESTROY <D>
MOV A,D
CPI NMBCNS
JC TBLJMP
POP PSW ; THROW AWAY TABLE ADDRESS
XRA A
RET
TBLJMP: ; COMPUTE AND JUMP TO HANDLER
; A = TABLE INDEX
ADD A ; DOUBLE TABLE INDEX FOR ADR OFFST
POP H ; RETURN ADR POINTS TO JUMP TBL
MOV E,A
MVI D,0
DAD D ; ADD TABLE INDEX * 2 TO TBL BASE
MOV E,M ; GET HANDLER ADDRESS
INX H
MOV D,M
XCHG
PCHL ; JUMP TO COMPUTED CNS HANDLER
PAGE
;---------------------------------------------------------------
;
; SERIAL PORT ADDRESS EQUATES
;
;---------------------------------------------------------------
DATA0 EQU 01CH ;CONSOLE #0 DATA
STS0 EQU DATA0+1 ;CONSOLE #0 STATUS
DATA1 EQU 02CH ;CONSOLE #1 DATA
STS1 EQU DATA1+1 ;CONSOLE #1 STATUS
DATA2 EQU 02EH ;CONSOLE #2 DATA
STS2 EQU DATA2+1 ;CONSOLE #2 STATUS
DATA3 EQU 02AH ;CONSOLE #3 DATA
STS3 EQU DATA3+1 ;CONSOLE #3 STATUS
LPTPRT0 EQU 01EH ;PRINTER #0 DATA
LPTSTS0 EQU LPTPRT0+1 ;PRINTER #0 STATUS
LPTPRT1 EQU 028H ;PRINTER #1 DATA
LPTSTS1 EQU LPTPRT1+1 ;PRINTER #1 STATUS
PAGE
;---------------------------------------------------------------
;
; POLL CONSOLE # 0 INPUT
;
;---------------------------------------------------------------
POLCI0:
PT0ST: ; TEST CONSOLE STATUS
XRA A ; RETURN 0FFH IF READY
OUT STS0 ; 000H IF NOT
IN STS0 ;
ANI 1 ; RX CHAR ?
RZ ; NO
MVI A,0FFH ; YES - SET FLAG
RET ;
;
;---------------------------------------------------------------
;
; CONSOLE # 0 INPUT
;
;---------------------------------------------------------------
;
PT0IN: ; RETURN CHAR IN REG A
MVI C,POLL ;
MVI E,PLCI0 ; POLL CONSOLE #0 INPUT
CALL XDOS ;
IN DATA0 ; READ CHARACTER
ANI 7FH ; STRIP PARITY
RET ;
;
;
;---------------------------------------------------------------
;
; CONSOLE # 0 OUTPUT
;
;---------------------------------------------------------------
;
PT0OUT: ; REG C = CHAR TO OUTPUT
PUSH B ;
MVI C,POLL ;
MVI E,PLCO0 ;
CALL XDOS ; POLL CONSOLE #0 OUTPUT
POP B ;
MOV A,C ;
OUT DATA0 ; TRANSMIT CHARACTER
RET ;
;
;
;---------------------------------------------------------------
;
; POLL CONSOLE # 0 OUTPUT
;
;---------------------------------------------------------------
;
POLCO0: ; RETURN 0FFH IF READY
MVI A,10H ; 000H IF NOT
OUT STS0 ; RESET INT BIT
IN STS0 ; READ STATUS
ANI 0CH ; MASK FOR DTR AND TXE
CPI 0CH ; MUST HAVE BOTH
MVI A,0 ;
RNZ ; RETURN NOT READY
MVI A,0FFH ;
RET ; RETURN READY
PAGE
;---------------------------------------------------------------
;
; POLL CONSOLE # 1 INPUT
;
;---------------------------------------------------------------
POLCI1:
PT1ST: ; TEST CONSOLE STATUS
XRA A ; RETURN 0FFH IF READY
OUT STS1 ; 000H IF NOT
IN STS1 ;
ANI 1 ; RX CHAR ?
RZ ; NO
MVI A,0FFH ; YES - SET FLAG
RET ;
;
;---------------------------------------------------------------
;
; CONSOLE # 1 INPUT
;
;---------------------------------------------------------------
;
PT1IN: ; RETURN CHAR IN REG A
MVI C,POLL ;
MVI E,PLCI1 ; POLL CONSOLE #1 INPUT
CALL XDOS ;
IN DATA1 ; READ CHARACTER
ANI 7FH ; STRIP PARITY
RET ;
;
;
;---------------------------------------------------------------
;
; CONSOLE # 1 OUTPUT
;
;---------------------------------------------------------------
;
PT1OUT: ; REG C = CHAR TO OUTPUT
PUSH B ;
MVI C,POLL ;
MVI E,PLCO1 ;
CALL XDOS ; POLL CONSOLE #1 OUTPUT
POP B ;
MOV A,C ;
OUT DATA1 ; TRANSMIT CHARACTER
RET ;
;
;
;---------------------------------------------------------------
;
; POLL CONSOLE # 1 OUTPUT
;
;---------------------------------------------------------------
;
POLCO1: ; RETURN 0FFH IF READY
MVI A,10H ; 000H IF NOT
OUT STS1 ; RESET INT BIT
IN STS1 ; READ STATUS
ANI 0CH ; MASK FOR DTR AND TXE
CPI 0CH ; MUST HAVE BOTH
MVI A,0 ;
RNZ ; RETURN NOT READY
MVI A,0FFH ;
RET ; RETURN READY
PAGE
;---------------------------------------------------------------
;
; POLL CONSOLE # 2 INPUT
;
;---------------------------------------------------------------
POLCI2:
PT2ST: ; TEST CONSOLE STATUS
XRA A ; RETURN 0FFH IF READY
OUT STS2 ; 000H IF NOT
IN STS2 ;
ANI 1 ; RX CHAR ?
RZ ; NO
MVI A,0FFH ; YES - SET FLAG
RET ;
;
;---------------------------------------------------------------
;
; CONSOLE # 2 INPUT
;
;---------------------------------------------------------------
;
PT2IN: ; RETURN CHAR IN REG A
MVI C,POLL ;
MVI E,PLCI2 ; POLL CONSOLE #2 INPUT
CALL XDOS ;
IN DATA2 ; READ CHARACTER
ANI 7FH ; STRIP PARITY
RET ;
;
;
;---------------------------------------------------------------
;
; CONSOLE # 2 OUTPUT
;
;---------------------------------------------------------------
;
PT2OUT: ; REG C = CHAR TO OUTPUT
PUSH B ;
MVI C,POLL ;
MVI E,PLCO2 ;
CALL XDOS ; POLL CONSOLE #2 OUTPUT
POP B ;
MOV A,C ;
OUT DATA2 ; TRANSMIT CHARACTER
RET ;
;
;
;---------------------------------------------------------------
;
; POLL CONSOLE # 2 OUTPUT
;
;---------------------------------------------------------------
;
POLCO2: ; RETURN 0FFH IF READY
MVI A,10H ; 000H IF NOT
OUT STS2 ; RESET INT BIT
IN STS2 ; READ STATUS
ANI 0CH ; MASK FOR DTR AND TXE
CPI 0CH ; MUST HAVE BOTH
MVI A,0 ;
RNZ ; RETURN NOT READY
MVI A,0FFH ;
RET ; RETURN READY
PAGE
;---------------------------------------------------------------
;
; POLL CONSOLE # 3 INPUT
;
;---------------------------------------------------------------
POLCI3:
PT3ST: ; TEST CONSOLE STATUS
XRA A ; RETURN 0FFH IF READY
OUT STS3 ; 000H IF NOT
IN STS3 ;
ANI 1 ; RX CHAR ?
RZ ; NO
MVI A,0FFH ; YES - SET FLAG
RET ;
;
;---------------------------------------------------------------
;
; CONSOLE # 3 INPUT
;
;---------------------------------------------------------------
;
PT3IN: ; RETURN CHAR IN REG A
MVI C,POLL ;
MVI E,PLCI3 ; POLL CONSOLE #3 INPUT
CALL XDOS ;
IN DATA3 ; READ CHARACTER
ANI 7FH ; STRIP PARITY
RET ;
;
;
;---------------------------------------------------------------
;
; CONSOLE # 3 OUTPUT
;
;---------------------------------------------------------------
;
PT3OUT: ; REG C = CHAR TO OUTPUT
PUSH B ;
MVI C,POLL ;
MVI E,PLCO3 ;
CALL XDOS ; POLL CONSOLE #3 OUTPUT
POP B ;
MOV A,C ;
OUT DATA3 ; TRANSMIT CHARACTER
RET ;
;
;
;---------------------------------------------------------------
;
; POLL CONSOLE # 3 OUTPUT
;
;---------------------------------------------------------------
;
POLCO3: ; RETURN 0FFH IF READY
MVI A,10H ; 000H IF NOT
OUT STS3 ; RESET INT BIT
IN STS3 ; READ STATUS
ANI 0CH ; MASK FOR DTR AND TXE
CPI 0CH ; MUST HAVE BOTH
MVI A,0 ;
RNZ ; RETURN NOT READY
MVI A,0FFH ;
RET ; RETURN READY
PAGE
;---------------------------------------------------------------
;
; LINE PRINTER #0 DRIVER
;
;---------------------------------------------------------------
;
LIST: ;LIST OUTPUT #0
PUSH B ;
MVI C,POLL ; POLL PRINTER STATUS
MVI E,PLLPT ;
CALL XDOS ;
POP B ;
MOV A,C ; CHARACTER TO PRINT
OUT LPTPRT0 ;
cpi 0ch ;** form feed test for tty 40
rnz
mvi c,0 ;** output a null
call list
jmp list
;
;---------------------------------------------------------------
;
; POLL PRINTER OUTPUT
;
;---------------------------------------------------------------
;
POLLPT: ; RETURN 0FFH IF READY
MVI A,10H ; 000H IF NOT
OUT LPTSTS0 ; RESET INT BIT
IN LPTSTS0 ; READ STATUS
ANI 0CH ; MASK FOR DTR AND TXE
CPI 0CH ; MUST HAVE BOTH
MVI A,0 ;
RNZ ; RETURN NOT READY
MVI A,0FFH ;
RET ; RETURN READY
;
PAGE
;
; MP/M 1.0 EXTENDED I/O SYSTEM
;
;
POLLDEVICE:
; REG C = DEVICE # TO BE POLLED
; RETURN 0FFH IF READY,
; 000H IF NOT
MOV A,C
CPI NMBDEV
JC DEVOK
MVI A,NMBDEV; IF DEV # >= NMBDEV,
; SET TO NMBDEV
DEVOK:
CALL TBLJMP ; JUMP TO DEV POLL CODE
DEVTBL:
DW POLLPT ; POLL PRINTER OUTPUT
DW POLCO0 ; POLL CONSOLE #0 OUTPUT
DW POLCO1 ; POLL CONSOLE #1 OUTPUT
DW POLCO2 ; POLL CONSOLE #2 OUTPUT
DW POLCO3 ; POLL CONSOLE #3 OUTPUT
DW POLCI0 ; POLL CONSOLE #1 INPUT
DW POLCI1 ; POLL CONSOLE #1 INPUT
DW POLCI2 ; POLL CONSOLE #1 INPUT
DW POLCI3 ; POLL CONSOLE #1 INPUT
NMBDEV EQU ($-DEVTBL)/2
DW RTNEMPTY; BAD DEVICE HANDLER
PAGE
; SELECT / PROTECT MEMORY
SELMEMORY:
; REG BC = ADR OF MEM DESCRIPTOR
; BC -> BASE 1 BYTE,
; SIZE 1 BYTE,
; ATTRIB 1 BYTE,
; BANK 1 BYTE.
;
; BIOS TABLE MODIFIED
CPI 20H ;
JZ $
LXI H,3 ; POINT TO BANK
DAD B ;
MOV A,M ; GET IT
STA BANKNO ; SAVE BANK NUMBER
RAL ;
RAL ;
RAL ;
ANI 018H ; MASK FOR PIO
ORI MEMSK ;
STA CURMEM ; STORE CURRENT BANK MASK
OUT 009H ; SET PIO
RET
BANKNO: DB 0 ; LAST SELECTED MEMORY BANK NUMBER
CURMEM: DB 0 ; LAST SELECTED MEMORY BANK MASK
; START CLOCK
STARTCLOCK:
; WILL CAUSE FLAG #1 TO BE SET
; AT EACH SYSTEM TIME UNIT TICK
MVI A,0FFH
STA TICKN
RET
; STOP CLOCK
STOPCLOCK:
; WILL STOP FLAG #1 SETTING AT
; SYSTEM TIME UNIT TICK
XRA A
STA TICKN
RET
; EXIT REGION
EXITREGION:
; EI IF NOT PREEMPTED
LDA PREEMP
ORA A
RNZ
EI
RET
; MAXIMUM CONSOLE NUMBER
MAXCONSOLE:
MVI A,NMBCNS
RET
; MP/M 1.0 INTERRUPT HANDLERS
DSPTCH EQU 142
INT1HND:
; INTERRUPT 1 HANDLER ENTRY POINT
;
T20MS:
SHLD SVDHL
LXI H,TIMERINT
JMP INTINIT
TIMERINT:
LDA TICKN
ORA A ; TEST TICKN, INDICATES
; DELAYED PROCESS(ES)
JZ NOTICKN
MVI C,FLAGST
MVI E,1
CALL XDOS ; SET FLAG #1 EACH TICK
NOTICKN:
LXI H,CNTx
DCR M ; DEC TICK CNTR
JNZ NOT1SEC
mvi a,125
dcx h
sub m
mov m,a ;** toggle count 62 <-> 63
inx h
mov m,a ;** actual #/sec = 62.5
MVI C,FLAGST
MVI E,2
CALL XDOS ; SET FLAG #2 @ 1 SEC
NOT1SEC:
INTDONE:
XRA A
STA PREEMP ; CLEAR PREEMPTED FLAG
POP B
POP D
LHLD SVDSP
SPHL ; RESTORE STK PTR
POP PSW
LHLD SVDRET
PUSH H
LXI H,PDISP ; MP/M DISPATCH
PUSH H ; PUT ON STACK FOR RETURN
LHLD SVDHL
; THE FOLLOWING DISPATCH CALL WILL FORCE ROUND ROBIN
; SCHEDULING OF PROCESSES EXECUTING AT THE SAME PRIORITY
; EACH 1/32ND OF A SECOND.
; NOTE: INTERRUPTS ARE NOT ENABLED UNTIL THE DISPATCHER
; RESUMES THE NEXT PROCESS. THIS PREVENTS INTERRUPT
; OVER-RUN OF THE STACKS WHEN STUCK OR HIGH FREQUENCY
; INTERRUPTS ARE ENCOUNTERED.
RETI ; DISPATCH
INTINIT: ;SAVE MACHINE STATE FOR INTRPT HNDLNG
SHLD ADRINTHD
POP H
SHLD SVDRET
PUSH PSW
LXI H,0
DAD SP
SHLD SVDSP ; SAVE USERS STK PTR
LXI SP,LSTINTSTK ; LCL STK FOR INTR HNDL
PUSH D
PUSH B
MVI A,0FFH
STA PREEMP ; SET PREEMPTED FLAG
LHLD ADRINTHD
PCHL ;JUMP TO INTERRUPT HANDLER
;
; BIOS DATA SEGMENT
;
togcnt: db 62 ; toggle counter 62 <-> 63
CNTx: DB 62 ; TICK CNTR to 1 SEC
INTSTK: ; LOCAL INTRPT STK
DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H
DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H
DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H
DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H
LSTINTSTK:
ADRINTHD: DW 0 ; INTERRUPT HANDLER ADDRESS
SVDHL: DW 0 ; SAVED REGS HL DURING INT HNDL
SVDSP: DW 0 ; SAVED SP DURING INT HNDL
SVDRET: DW 0 ; SAVED RETURN DURING INT HNDL
TICKN: DB 0 ; TICKING BOOLEAN,TRUE = DELAYED
PREEMP: DB 0 ; PREEMPTED BOOLEAN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
; THIS IS DISK WAIT ENTRY
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
WAIT0:
PUSH B ; SAVE RETRY COUNT
MVI C,FLAGWT ; FUNCTION FLAG WAIT
MVI E,5 ; DEVICE IS DISK
CALL XDOS
POP B ; RESTORE RETRY COUNTER IN <C>
; READ OR WRITE IS OK, ACCUMULATOR CONTAINS ZERO
RET
PAGE
;-----------------------------------------------------------------------
;
; THIS IS THE DELAY ROUTINE. IT WILL LOOP HERE FOR THE
; NUMBER OF MILLISECONDS SPECIFIED IN REGISTER C.
;
;-----------------------------------------------------------------------
DELAY:
DEL1: MVI B,100 ;FORCE DELAY FOR 1 MILLISECOND
DEL2: RLC ;INSTRUCTIONS TO FILL IN TIME
DAD H ;
DAD H ;
DCR B ;AT ONE MILLISECOND YET ??
JNZ DEL2 ;NO, KEEP ON LOOPING
DCR C ;END OF REQUESTED INTERVAL YET ??
JNZ DEL1 ;NO, KEEP ON
RET ;RETURN TO CALLER
PAGE
;********************************************
;* NOTE: THE INITIALIZATION CODE WILL BE
;* OVERWRITTEN BY DIRBUF & FPYBUF
;********************************************
DIRBUF EQU $
;------------------------------------------------------------
;
; INITIALIZE MP/M: REAL TIME CLOCK & DISKS
;
;------------------------------------------------------------
SYSTEMINIT:
DI
; C = BREAKPOINT RESTART NUMBER
; DE = BREAKPOINT RESTART HANDLER ADDRESS
; HL = DIRECT XIOS INTERCEPT JUMP TABLE ADDRESS
SHLD SVDJT
MOV L,C
MVI H,0
DAD H
DAD H
DAD H ;HL = RESTART JUMP ADDRESS
SHLD SVDBPA
MVI A,01AH ; SELECT BANK 3
CALL STMVTR ; SET UP VECTORS
MVI A,012H ; SELECT BANK 2
CALL STMVTR ; SET UP VECTORS
MVI A,00AH ; SELECT BANK 1
CALL STMVTR ; SET UP VECTORS
MVI A,002H ; SELECT BANK 0
CALL STMVTR ; SET UP VECTORS
LXI B,003H ;SET THE MODE FOR DRIVES INITIALIZED BY "SETUP"
MODESET:
CALL SELDSK ;SELECT DRIVE FOR MODESET
LXI H,MODE ;
DAD B ;POINT TO CORRECT MODE BYTE
PUSH B ;SAVE COUNT OF DRIVES
MOV C,M ;
CALL SETMOD ;SET MODE
POP B ;
DCR C ;END OF LIST YET ??
JP MODESET ;SET MODE FOR ALL DRIVES
CALL SDCONF ;SET DISK CONFIGURATION
LXI B,80H
CALL SETDMA ;SET DMA ADDRESS
MVI A,INTERUPT SHR 8 ;SETUP INTERRUPT VECTOR
DB 0EDH,047H ;---- FAKE STAI INSTRUCTION
MVI A,60H ; SET VECTOR FOR CTC
OUT 30H ; CTC CHANNEL 0
MVI A,0A7H ; RESET / LOAD TIME CONSTANT
OUT 33H ; CHANNEL 3
MVI A,250 ; TIME CONSTANT
OUT 033H ;
IF HARDSK
EI
MVI A,080H ;ISSUE RESET AGAINST HARD DISK
OUT 023H ;
MVI A,01010000B ;RESET WRITE FAULT
OUT 020H ;DRIVE 1
MVI A,01100000B ;
OUT 020H ;DRIVE 2
MVI A,00010000B ;SELECT DRIVE 1/ HEAD 0
OUT 020H ;
MVI C,20 ;WAIT FOR 20 MILLISECONDS
CALL DELAY ;
CALL WAIT0 ;INTERRUPT PRODUCED BY HARD DISK RESET
XRA A ;ZERO ACCUMULATOR
STA HSTACT ;SET HOST BUFFER INACTIVE
STA UNACNT ;SET UNALLOCATED COUNT TO ZERO
LXI H,HSTBUF-1 ;SETUP WRITE CONTROL BYTE FOR HARD DISK
MVI M,00DH ;
ENDIF
RET ;
STMVTR:
OUT MEMPORT
MVI A,0C3H ; SET VECTORS FOR BDOS
STA 0 ; JMP INSTRUCTION
LHLD SVDJT ;
SHLD 1
LHLD SVDBPA
MOV M,A
INX H
MOV M,E
INX H
MOV M,D
RET ;
SVDJT: DS 2 ; SAVED DIRECT JUMP TABLE ADDRESS
SVDBPA: DS 2 ; SAVED BREAK POINT ADDRESS
;-----------------------------------------------------------------------
;
; DISK CONFIGURATION TABLE
;
;-----------------------------------------------------------------------
IF HARDSK
; PIN CONFIGURATION
DSCN0: DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 10H,00H,00H,00H,00H,00H,10H,00H ; 1
DB 90H,90H,90H,00H,00H,00H,00H,00H ; 2
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 10H,00H,00H,20H,00H,00H,10H,20H ; 4
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 90H,90H,90H,20H,00H,00H,00H,20H ; 6
DB 90H,90H,90H,0A0H,0A0H,0A0H,0H,0H ; 7
ENDIF
;-----------------------------------------------------------------------
;
; SET UP DISK CONFIGURATON
;
; [ THIS CODE EXECUTED ONLY ONCE ]
;
;-----------------------------------------------------------------------
;
SDCONF: LXI H,SEL0+2 ;POINT TO DRIVE C:
LDA MPARMS ;
ANI 05H ; TEST FOR FOUR FLOPPIES
JMP SDDBL ; YES SKIP THE ZAP
MOV M,A ;
INX H ; ZAP C: AND D:
MOV M,A ;
SDDBL:
LXI D,SEL0+4 ;POINT TO DRIVE E:
IF HARDSK
MVI A,1 ; *** TEMP DEBUG
; IN 025H ;READ CONFIGURATION PORT
ANI 07H ;STRIP OFF HIGH PART
RAL ;
RAL ;
RAL ;
MVI B,0 ;
MOV C,A ;POINT TO CONFIGURATION TABLE
LXI H,DSCN0 ;
DAD B ; INDEX TO RIGHT ENTRY
MVI B,8 ;
SDL1: MOV A,M ; CHANGE ALL SELECT MASKS
STAX D ;
SDOK: INX D ; NEXT
INX H ; DRIVE
DJNZ SDL1 ;
ENDIF
IF NOT HARDSK
XCHG ;
MVI B,8 ;
XRA A ;
SDL2: MOV M,A ; ZAP ALL HARD DRIVES
INX H ;
DJNZ SDL2 ;
ENDIF ;
RET
INITEND EQU $
PAGE
;-----------------------------------------------------------------------
;
; THE FOLLOWING AREA CONTAINS THE DISK/WORK SAVE AREAS
; USED BY THE CBIOS IN THE NORMAL COURSE OF ACTIVITY.
;
;-----------------------------------------------------------------------
TEMPBUF EQU (DIRBUF-BASE)+256
ORG TEMPBUF+((INITEND-BASE)/TEMPBUF)*((INITEND-BASE)-TEMPBUF)
BEGDAT EQU $ ;START OF BDOS AREAS
;DIRBUF: DS 128 ;OVERLAYS SYSTEMINIT CODE
ALV0: DS 32
CSV0: DS 32
ALV1: DS 32
CSV1: DS 32
ALV2: DS 32
CSV2: DS 32
ALV3: DS 32
CSV3: DS 32
IF HARDSK
ALV4: DS 64
CSV4: DS 0
ALV5: DS 64
CSV5: DS 0
ALV6: DS 64
CSV6: DS 0
ALV7: DS 64
CSV7: DS 0
ALV8: DS 64
CSV8: DS 0
ALV9: DS 64
CSV9: DS 0
ALVA: DS 36
CSVA: DS 0
ALVB: DS 36
CSVB: DS 0
DS 1 ;MUST PRECEDE HSTBUF
HSTBUF: DS 1024 ;HOST BUFFER AREA
DS 1 ;MUST FOLLOW HSTBUF
ENDIF
FPYBUF EQU DIRBUF+128 ; FLOPPY I/O BUFFER
NEWDSK: DS 1 ;SEEK DISK NUMBER
NEWTRK: DS 2 ;SEEK TRACK NUMBER
NEWSEC: DS 1 ;SEEK SECTOR NUMBER
HSTDSK: DS 1 ;HOST DISK NUMBER
HSTTRK: DS 2 ;HOST TRACK NUMBER
HSTSEC: DS 1 ;HOST SECTOR NUMBER
NEWHST: DS 1 ;SEEK SHR SECSHF
HSTACT: DS 1 ;HOST ACTIVE FLAG
HSTWRT: DS 1 ;HOST WRITTEN FLAG
UNACNT: DS 1 ;UNALLOCATED 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 OPERATION
WRTYPE: DS 1 ;WRITE OPERATION TYPE
CMD: DB 0 ;COMMANDS FOR NEXT I/O
MASK: DB 0 ;STATUS MASKS BUFFER FOR DISK I/O
STATUS: DB 0 ;STATUS SAVE LOCATION FOR DISK I/O
SAVE1: DB 000H,000H,000H,000H ;SAVE AREA FOR NMI ROUTINE
P$RETRIES: DB 000H ;COUNTER FOR PERMANENT ERRORS
T$RETRIES: DB 000H ;COUNTER FOR TEMPORARY ERRORS
DATSIZE EQU $-BEGDAT
END