Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,454 @@
TITLE 'MP/M LOADER, COPYRIGHT 1979, ALTOS COMPUTER SYSTEMS'
;-----------------------------------------------------------------------
;
; ALTOS COMPUTER SYSTEMS
; 2338A WALSH AVENUE
; SANTA CLARA, CA 95050
;
; (408) 244-5766
;
; COPYRIGHT 1979, ALTOS COMPUTER SYSTEMS
;
; THIS PROGRAM IS INTENDED TO PERFORM THE LOADING OF THE
; CCP AND BDOS INTO MEMORY DURING THE FIRST COLD START
; OF THE ALTOS SYSTEM.
; ONCE THE SYSTEM IS LOADED IT WILL LOAD THE FULL CBIOS
; ROUTINES WHICH WILL CONTROL THE LOADING AND OPERATION
; OF THE SYSTEM FROM THAT POINT ONWARD.
; IF THE INITIAL LOAD OF THE SYSTEM IS UNABLE TO FIND THE
; FULL CBIOS ON THE CURRENT DISK IT WILL CONTINUE TO
; OPERATE BUT IN A DEGRADED MODE.
;
; VERSION: 2.00
; DATE: DECEMBER 5, 1979
; . INITIAL VERSION OF PROGRAM.
;
;-----------------------------------------------------------------------
MACLIB DISKDEF
MACLIB Z80S
VERSION EQU 20 ;CP/M VERSION NUMBER
ALTOSV EQU 0 ;ALTOS VERSION NUMBER
TRUE EQU 0FFFFH ;
FALSE EQU 00000H ;
;-----------------------------------------------------------------------
;
; THE FOLLOWING FIELDS ARE USER MODIFIABLE
;
;-----------------------------------------------------------------------
MSIZE EQU 32 ;
DMA EQU TRUE ;
HARDSK EQU TRUE ;
;-----------------------------------------------------------------------
;
; THE FOLLOWING CONSTANTS APPLY TO THE RELOCATION OF BIOS
;
;-----------------------------------------------------------------------
RELOC EQU TRUE ;
RAM$TOP EQU 1D00H ;TOP ADDRESS+1
BIOS EQU RAM$TOP-0600H ;BASIC INPUT/OUTPUT
BDOS EQU BIOS-0E00H ;BASE OF THE BDOS
ORG BIOS
BUFF EQU 080H ;DEFAULT BUFFER
RETRY EQU 10 ;MAX RETRIES ON DISK
;
; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
;
;-----------------------------------------------------------------------
jmp boot ;cold start
wboote: jmp wboot ;warm start
jmp const ;console status
jmp conin ;console character in
jmp conout ;console character out
jmp list ;list character out
jmp punch ;punch character out
jmp reader ;reader character out
jmp home ;move head to home position
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 listst ;return list status
jmp sectran ;sector translate
PAGE
;-----------------------------------------------------------------------
;
; FIXED TABLES FOR TWO DRIVE MINIMAL STANDARD SYSTEM
;
; THE LOCATION OF THE FOLLOWING TABLES MUST NOT BE
; CHANGED AS EXTERNAL PROGRAMS RELY ON THEIR
; POSITION IN THIS PROGRAM.
;
;-----------------------------------------------------------------------
TRKM: DB 000H,000H,000H,000H ;TRACK REGISTERS
SELM: DB 004H,008H,010H,020H ;DENSITY MASKS UPDATED BY SETUP
MODM: DB 000H,000H,000H,000H ;MODE MASKS UPDATED BY SETUP
PTR1: DB 047H,00DH ;9600 BAUD SETUP FOR PRINTER 1
PTR2: DB 047H,00DH ;9600 BAUD SETUP FOR AUXILLIARY PORT
DPBASE: ;THESE BLOCKS ARE UPDATED BY SETUP
; DISK PARAMETER HEADER FOR DISK 00 (A:)
DW XLT00,0000H
DW 0000H,0000H
DW DIRBF,SDBLK
DW CHK00,ALL00
XLT00: db 01,07,13,19,25,05,11,17,23,03,09,15,21
db 02,08,14,20,26,06,12,18,24,04,10,16,22
XLT01: 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
;-----------------------------------------------------------------------
;
; DISK PARAMETER BLOCKS
;
;-----------------------------------------------------------------------
SDBLK: ;DISK PARAMETER BLOCK FOR SINGLE DENSITY
dw 26 ;sectors per track
db 3 ;block shift factor
db 7 ;block mask
db 0 ;null mask
dw 242 ;disk size-1
dw 63 ;directory max
db 192 ;alloc 0
db 0 ;alloc 1
dw 16 ;check size
dw 2 ;track offset
DDBLK: DW 48 ;SECTORS PER TRACK
DB 4 ;BLOCK SHIFT FACTOR
DB 15 ;BLOCK MASK
DB 0 ;EXTENT MASK
DW 224 ;DISK SIZE-1
DW 95 ;DIRECTORY MAX
DB 192 ;ALLOC 0
DB 0 ;ALLOC 1
DW 24 ;CHECK SIZE
DW 2 ;TRACK OFFSET
MPARMS: DW 0 ;MISC. PARAMETERS
;
; 0100H = DOUBLE HEADED FLOPPY DRIVES
; 0200H = CENTRONICS PRINTER IS LIST DEVICE
;
;-----------------------------------------------------------------------
;
; END OF FIXED LOCATION DEPENDENT TABLES
;-----------------------------------------------------------------------
PAGE
; COLD BOOT ROUTINE
;
BOOT: ;simplest case is to just perform parameter initialization
; INTERRUPT VECTOR AND ROUTINE
WBOOT: ;SIMPLEST CASE IS TO DO A COLD BOOT
gocpm:
DI
MVI A,INTERUPT SHR 8
STAI
MVI A,INTERUPT AND 0FFH
OUT 00AH
EI
RET
;
CONST: ;console status, return 0ffh if character ready, 00h if not
XRA A ;CHECK STATUS
OUT 01DH ;
IN 01DH ;
ANI 00000001B ;CHARACTER WAITING ??
RZ ;NO, RETURN
MVI A,0FFH ;RETURN ALL FOXES
ret
CONIN: ;console character into register a
CALL CONST ;CHARACTER WAITING ??
JZ CONIN ;NOT YET....
IN 01CH ;READ CHARACTER IN
ANI 07FH ;MAKE SURE ITS ASCII
ret
CONOUT: ;console character output from register c
MVI A,010H ;RESET INT BIT
OUT 01DH ;
IN 01DH ;GET STATUS
ANI 00001100B ;TXE AND DTR
CPI 00001100B ;READY ??
JNZ CONOUT ;NO, WAIT HERE
MOV A,C ;Get to accumulator
OUT 01CH ;WRITE IT ONTO CONSOLE
ret
LIST: ;list character from register c
MVI A,010H ;RESET INT BIT
OUT 01FH ;
IN 01FH ;GET STATUS
ANI 00001100B ;TXE AND DTR
CPI 00001100B ;READY ??
JNZ LIST ;NO, WAIT HERE
MOV A,C ;Get to accumulator
OUT 01EH ;WRITE IT ONTO PRINTER
ret ;RETURN TO CALLER
LISTST: ;return list status (0 if not ready, 1 if ready)
xra a ;0 is always ok to return
ret
PUNCH: ;punch character from register c
ret ;null subroutine
READER: ;read character into register a from reader device
mvi a,1ah ;enter end of file for now (replace later)
ret
PAGE
;-----------------------------------------------------------------------
;
; THESE ARE THE DISK I/O ROUTINES.
; THESE ROUTINES WILL BE USED BY THE BDOS DURING
; THE LOAD OF THE FULL CBIOS. FOLLOWING THE SUCCESSFUL
; LOAD THEY WILL NO LONGER BE USED.
;
;-----------------------------------------------------------------------
HOME: ;move to the track 00 position of current drive
CALL POINT ;POINT TO TRACK REGISTER
MVI M,000H ;SET TO TRACK ZERO
MVI A,00AH ;HOME COMMAND
OUT 004H ;DO IT
WT1: JR WT1 ;WAIT HERE UNTIL FINISHED
ret ;RETURN TO CALLER
SELDSK: ;select disk given by register C
CALL WBOOT
lxi h,0000h ;error return code
mov a,c ;
ORA A ;MUST BE ONLY 0
RNZ ;INVALID FOR LOADER.
STA DISKNO ;UPDATE DISK NUMBER
CALL POINT ;
MOV A,M ;LOAD LAST TRACK NUMBER
OUT 005H ;RESETUP 1791
LXI D,004H ;POINT TO DENSITY REGISTER
DAD D ;
MOV A,M ;PICKUP MASK
OUT 008H ;WITHE IT OUT TO SELECT DRIVE
; compute proper disk parameter header address
LXI H,DPBASE ;ONLY ONE SO ITS EASY....
ret
SETTRK: ;set track given by register c
CALL POINT ;POINT TO LAST TRACK REGISTER
mov a,c ;
CMP M ;SAME TRACK AS LAST TIME ??
RZ ;YES, NO NEED TO SEEK
MOV M,A ;
OUT 007H ;
MVI A,01AH ;SEEK TO CORRECT TRACK
OUT 004H ;DO IT....
STWT: JR STWT ;WAIT FOR SEEK TO COMPLETE
ret
SETSEC: ;set sector given by register c
mov a,c ;WRITE SECTOR OUT
OUT 006H ;
ret
SECTRAN:
;translate the sector given by BC using the
;translate table given by DE
xchg ;HL=.trans
dad b ;HL=.trans(sector)
mov l,m ;L = trans(sector)
mvi h,0 ;HL= trans(sector)
ret ;with value in HL
SETDMA: ;set dma address given by registers b and c
mov l,c ;low order address
mov h,b ;high order address
shld dmaad ;save the address
ret
READ: ;perform read operation (usually this is similar to write
; so we will allow space to set up read command, then use
; common code in write)
MVI A,08CH ;READ COMMAND CODE
MVI B,001H ;DMA READ CODE
MVI C,09FH ;READ STATUS MASK
jmp waitio ;to perform the actual i/o
ORG (($+0A2H) AND 0FF00H)+5EH
INTERUPT:
DW IRTN
IRTN:
POP H ;PICKUP PC
INX H ;BUMP PAST JR $
INX H ;
PUSH H ;PUT IT BACK FOR RETI
EI ;
RETI ;
WRITE: ;perform a write operation
MVI A,0ACH ;WRITE COMMAND CODE
MVI B,005H ;DMA WRITE CODE
MVI C,0FFH ;WRITE STATUS MASK
waitio: ;enter here from read and write to perform the actual i/o
; operation. return a 00h in register a if the operation completes
; properly, and 01h if an error occurs during the read or write
PUSH PSW ;SAVE I/O COMMAND CODE
IN 008H ;IS HEAD LOADED ??
ANI 00000010B ;CHECK
MVI D,0FBH ;ASSUME YES
JNZ $+3+2 ;VERIFY ASSUMPTION
MVI D,0FFH ;ITS NOT, LEAVE HEAD LOAD BIT IN COMMAND
POP PSW ;RESTORE COMMAND
ANA D ;RESET HEAD LOAD BASED ON PREVIOUS TEST
IF DMA ;GENERATE DMA SUPPORT
PUSH PSW ;SAVE COMMAND
PUSH B ;SAVE REST
MOV A,B ;
STA DMALST3 ;SAVE READ/WRITE CODE BYTE
LXI B,01100H ;17 BYTES OF DATA AND PORT ZERO
LXI H,DMALIST ;
OUTIR ;WRITE IT OUT
POP B ;
POP PSW ;
ENDIF ;
PUSH B ;SAVE STATUS MASK
IF NOT DMA ;NON DMA SOFTWARE
PUSH PSW ;SAVE PSW
MOV A,B ;GET DMA I/O COMMAND (001 OR 005)
ANI 00000100B ;REMOVE ALL BUT TEST BIT
RRC ;
RRC ;
LHLD LOWSTR ;LOW MEMORY INI/RETN
ORA H ;MAKE INTO AN OTI IF NECESSARY
MOV H,A ;
SHLD 066H ;SAVE AT NMI LOCATION
LHLD LOWSTR+2 ;
SHLD 066H+2 ;
POP PSW ;RESTORE PSW
LHLD DMAAD ;POINT TO RECORD AREA
MVI C,007H ;PORT ADDRESS FOR I/O
ENDIF ;END NON DMA SOFTWARE
OUT 004H ;PERFORM COMMAND
RDLP: JR RDLP ;WAIT HERE
IN 004H ;READ STATUS
POP B ;
ANA C ;IS STATUS OK ??
RZ ;YES, RETURN OK
mvi a,1 ;error condition
ret ;RETURN IN ERROR
POINT:
LHLD DISKNO ;CURRENT DRIVE
MVI H,000H ;
LXI D,TRKM ;
DAD D ;
RET ;POINT TO CURRENT TRACK REGISTER
MSPRT:
MOV A,M ;
ORA A ;END OF MESSAGE ??
RZ ;YES
INX H ;
MOV C,A ;
CALL CONOUT ;
JMP MSPRT ;
PAGE
;-----------------------------------------------------------------------
;
; CONSTANTS AND WORK AREAS
;
;-----------------------------------------------------------------------
DISKNO: DS 1 ;DISK NUMBER 0-15
TRACK: DS 1 ;TRACK NUMBER
SECTOR: DS 1 ;
IF DMA ;DMA SUPPORT SOFTWARE
DMALIST:DB 0C3H,07DH ;
DMAAD: DS 2 ;DIRECT MEMORY ADDRESS
DW 128-1 ;LENGTH FOR I/O
DB 014H,028H,085H,007H,08AH,0CFH,001H,0CFH
DMALST3:DS 1 ;001=READ, 005=WRITE
DB 0CFH,087H ;
ENDIF ;
IF NOT DMA ;NON DMA SUPPORT SOFTWARE
DMAAD: DS 2 ;DIRECT MEMORY ADDRESS
LOWSTR: INI ;
RETN ;
ENDIF ;
MSG: DB 00DH,00AH
IF RELOC
MSZ: DB '00'
ENDIF
IF NOT RELOC
MSZ: DB MSIZE/10+'0',MSIZE MOD 10 + '0'
ENDIF
DB 00DH,00AH,000H
NOMSG: DB 00DH,00AH
DB 'CBIOS00.COM NOT FOUND ON DISK, CORRECT AND RETRY '
DB 00DH,00AH,000H
LDRSIZ EQU $-BIOS ;LOADER SIZE IN BYTES
LDRPAG EQU (LDRSIZ+255)/256;LOADER SIZE IN PAGES
;-----------------------------------------------------------------------
;
; THE remainder of the CBIOS is reserved uninitialized
; data area, and does not need to be a part of the
; system memory image (the space must be available,
; however, between "begdat" and "enddat").
;
;-----------------------------------------------------------------------
begdat equ $ ;beginning of data area
dirbf: ds 128 ;scratch directory area
all00: ds 31 ;allocation vector 0
chk00: ds 16 ;check vector 0
enddat equ $ ;end of data area
datsiz equ $-begdat;size of data area
end


File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,188 @@
; BOOTSTRAP LOADER
;VERSION 4.2
;FOR USE WITH THE FDC-3 CONTROLLER BOARD IN EITHER SINGLE OR DOUBLE
;DENSITY ON THE DSC-2 COMPUTER SYSTEMS.
;
;SET THE VALUE DOUBLE ACCORDINGLY IF ASSEMBLING THIS FOR A
;SINGLE DENSITY SYSTEM
;THE IOBYTE IS IMPLEMENTED IN THE VERSION
;AND IS INITIALIZED WITH THE LIST DEVICE GOING TO SERIAL PORT1
TRUE EQU 0FFFH
FALSE EQU NOT TRUE
;
;
;
DOUBLE EQU TRUE ;THIS SHOULD BE FALSE FOR SINGLE DENSITY
;
ORG 00H
;
MSIZE EQU 64
sys$top equ msize*1024
bios equ sys$top-6*256
bdos equ bios-0e00h
ccp equ bdos-0800h
warm$boot equ ccp-0080h
;
PORT EQU 4AH
LAST EQU 26 ;LAST SECTOR ON TRK1 TO LOAD
SKIP EQU 1 ;NUMBER OF SECTORS TO SKIP
;
INIT0 EQU ((SKIP+1) SHL 8) OR 0 ;INITIAL TRACK,SECTOR
END0 EQU (0 SHL 7) OR 27 ;END OF FIRST TRK
INIT1 EQU (129 SHL 8) OR 1 ;TRACK,SECT ON TRK 1
END1 EQU (1 SHL 7) OR LAST+1 ;LAST POSITION ON TRK 1
ERR EQU 0F0H ;ERROR CONDITIONS
IOF EQU 08H ;IO FINISH
IOBYTE EQU 3
;
;
T76 EQU 04H ;TOWARD 76
STT EQU 06H ;TOWARD 76 AND STEP PULSE
DOUT EQU 80H ;DISK OUTPUT PORT
DINP EQU 80H ;DISK INPUT PORT
DMAH EQU 81H ;HIGH ORDER DMA ADDRESS
DMAL EQU 82H ;LOW ORDER DMA ADDRESS
COMMAND2 EQU 83H ;SECOND COMMAND PORT
RDS EQU 040H ;READ SECTOR
;RS232 PORTS
DATA EQU 40H
STATUS EQU 41H
STATUS1 EQU 49H
STATUS2 EQU 51H
STATUS3 EQU 59H
;
;
; INITIALIZE TRK/SEC AND DMA ADDRESS
START:
LXI D, INIT0
LXI H, warm$boot-3
;
READL: ;READ LOOP
SPHL ;SET THE STACK POINTER
; SEND DMA ADDRESS
MOV A,H
OUT DMAH
MOV A,L
OUT DMAL
;
; SET UP TRACK AND SECTOR
;
MOV L,E ;TRACK TO L
MOV A,D ;SECTOR TO A
ANI 7FH ;CLEAR HIGH BIT
MOV H,A ;SECTOR TO H
XTHL ;SET TRK AND SECTOR
INX SP ;ADJUST STACK POINTER
POP B
; PERFORM THE READ
MVI A,RDS
OUT DOUT
;
WRD: IN DINP
ANI ERR
JZ NERROR
;
; ERROR, REBOOT
;A HLT DOES A REBOOT AUTOMATICALLY ON DSC-2
HLT
;
;
NERROR: ;NO ERROR SO FAR
IN DINP
ANI IOF
JZ WRD ;GO BACK AND WAIT
;
; I/O FINISH,
; REPLACE DATA BYTES
PUSH B ;REPLACE 1 BYTE
INX SP ;ADJUST STACK POINTER
PUSH H ;REPLACE 2 BYTES
;
; ADD 128 TO DMA ADDRESS
LXI H,128
DAD SP
;
; INC TRACK/SECTOR
INR D
MOV A,D
CPI END0 ;END OF TRACK 0?
JNZ CMP1
;
; STEP TRACK TO TRACK 1
MVI A,STT
OUT DOUT
MVI A,T76
OUT DOUT
WST: ;WAIT FOR STEP AND HEAD SETTLE
MVI A,18D
WST0:
MVI C,0AAH ;ONE MILLISECOND TIMING
WST2:
DCR C
JNZ WST2
DCR A
JNZ WST0
;
; TRACK STEPPED
IF DOUBLE
;NOW CHANGE DENSITY
MVI A,8
OUT COMMAND2
ENDIF
;
LXI D,INIT1
MOV A,D
CMP1: CPI END1 ;END OF TRACK 1?
JNZ READL ;GO BACK FOR MORE
;
; END OF LOAD
LXI H,PORT
;
IF DOUBLE
;INIT FOR DOUBLE DENSITY
MVI M,8
INX H
MVI M,8
INX H ;POINT TO DENSITY SELECT
MVI M,0FH ;DOUBLE DENSITY
ENDIF
;
IF NOT DOUBLE
MOV M,H ;H IS 0
INX H
MOV M,H
INX H ;POINT TO DENSITY SELECT
MVI M,00 ;SINGLE DENSITY
ENDIF
;
;SET LOC 4 TO CONTAIN ACTIVE DRIVE = 0
MVI L,4
MOV M,H
;
; INITIALIZE THE I/O BYTE
; CON:=TTY: (CONSOLE TO PORT0)
; RDR:=PTR: (READER TO PORT2)
; PUN:=PTP: (PUNCH TO PORT2)
; LST:=CRT: (LIST TO PORT1)
;
MVI A,01$01$01$00B
STA IOBYTE
;
;INITIALIZE THE USARTS
MVI A,0CEH
OUT STATUS
OUT STATUS1
OUT STATUS2
MVI A,27H
OUT STATUS
OUT STATUS1
OUT STATUS2
IN DATA
;
JMP bios ;GO DO MORE INITIALIZATION
;
END


View File

@@ -0,0 +1,677 @@
; Support for CP/M 2.0 added 5 Sept 79 - J R Pierce
;HARD DISK VERSION 8-26-79
; BIOS FOR MICRO-2 COMPUTER
;
;THE IOBYTE IS IMPLEMENTED
;
;INTERRUPTS ARE NOT IMPLEMENTED
;
maclib diskdef
ndisks equ 2
;
;THIS VERSION CONTAINS DISK DRIVERS FOR THE DIGITAL SYSTEMS
;FDC-3 CONTROLLER BOARD. THIS BOARD CAN HANDLE DOUBLE DENSITY
;
; NOTE : MSIZE DETERMINES WHERE THIS CBIOS IS LOCATED
VERS EQU 20
on equ 0ffffh
off equ 00000h
ldr equ on
long equ off
if long
biosbase equ 1b00h
else
biosbase equ 1700h
endif
if ldr
bios equ biosbase
bdos equ 0D00h
warmboot equ 0
msize equ 0
else
MSIZE EQU 64 ;CP/M VERSION MEMORY SIZE IN KILOBYTES
ramtop equ msize*1024
bios equ ram$top-6*256
bdos equ bios-0e00h
ccp equ bdos-0800h
warm$boot equ ccp-0080h
endif
org bios
; WE WILL USE A SCRATCH AREA STARTING AT 40H
SCRAT EQU 40H ;START OF SCRATCH AREA
TRACK EQU SCRAT ;CURRENT TRACK ON DRIVE 0
TRAK1 EQU TRACK+1 ;CURRENT TRACK ON DRIVE 1
TRAK2 EQU TRAK1+1
TRAK3 EQU TRAK2+1
SECTOR EQU TRAK3+1 ;CURRENTLY SELECTED SECTOR
DMAAD EQU SECTOR+1 ;CURRENT DMA ADDRESS
DISKNO EQU DMAAD+2 ;CURRENT DISK NUMBER
DUMMY EQU DISKNO+1 ;MUST BE 0 FOR DOUBLE ADD
ERRORS EQU DUMMY+1
PORT EQU 4AH
PORTOUT EQU PORT+1
DENSITY EQU PORTOUT+1
;
IOBYTE EQU 3
;
;SET UP INPUT OUTPUT PORTS
DATA EQU 40H
STATUS EQU DATA+1
DATA1 EQU 48H
STATUS1 EQU DATA1+1
DATA2 EQU 50H
STATUS2 EQU DATA2+1
PARALLEL EQU 61H
;
;
; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
JMP WARMBOOT ;COLD START
WBOTE:
JMP WBOOT ;WARM START
JMP CONST ;CONSOLE STATUS
JMP CONIN ;CONSOLE CHARACTER IN
JMP CONOUT ;CONSOLE CHARACTER OUT
JMP LIST ;LIST CHARACTER OUT
JMP PUNCH ;PUNCH CHARACTER OUT
JMP READER ;READER CHARACTER OUT
JMP HOME ;MOVE HEAD TO HOME POSITION
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 lstat ; list status routine
jmp sectran ; logical->physical sector mapping
;THE WARM BOOT ROUTINE EXPECTS TO FIND THE LOG ON MESSAGE HERE
;SINCE THERE WAS NOT ENOUGH ROOM IN IT
DW 0D0AH ;CR,LF
DB MSIZE/10+'0',MSIZE MOD 10+'0'
DB 'k CP/M Vers'
DB VERS/10+'0','.',VERS MOD 10+'0'
DB 0
;
; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION
;
WBOOT:
;READ IN TRACK 0 SECTOR 2 WHICH WILL DO THE REST OF THE WARM START
;
LXI SP,80H ;USE SPACE BELOW BUFFER FOR STACK
MVI C,0 ;SELECT DISK 0
CALL SELDSK
CALL HOME ;GO TO TRACK 00
;
;SET SINGLE DENSITY
LDA PORT
ANI 0F7H
STA PORT
;SET DMA ADDRESS TO 80 BELOW START OF CCP
LXI B,WARMBOOT
CALL SETDMA
MVI C,2
CALL SETSEC
;NOW READ
CALL READ
ORA A ;ANY ERRORS?
JNZ WBOOT ;RETRY THE ENTIRE BOOT IF AN ERROR OCCURS
;
;
JMP WARMBOOT+3 ;GO FINISH THE WARM START
;I/O HANDLERS
;
CONST: CALL CONS
ORA A
RZ
MVI A,0FFH
RET
;
CONS:
CALL condsptch
DW TTYST
DW CRTST
DW BATST
DW UC1ST
;
CONIN:
CALL condsptch
DW TTYIN
DW CRTIN
DW BATIN
DW UC1IN
;
CONOUT:
CALL condsptch
DW TTYOUT
DW CRTOUT
DW BATOUT
DW UC1OUT
;
LIST:
LDA IOBYTE
RLC! RLC
CALL IODSPRLC
DW TTYOUT
DW CRTOUT
DW LPTOUT
DW UL1OUT
lstat: ; Dummy Routine
xra a ! ret
PUNCH:
LDA IOBYTE
RRC! RRC! RRC
CALL IODISPATCH
DW TTYOUT
DW PTPOUT
DW UP1OUT
DW UP2OUT
;
READER:
LDA IOBYTE
RRC
CALL IODISPATCH
DW TTYIN
DW PTRIN
DW UR1IN
DW UR2IN
;
condsptch:
lda io$byte
IODSPRLC:
RLC
IODISPATCH:
ANI 6H
XTHL ;GET TABLE ADDRESS
PUSH D
MOV E,A
MVI D,0
DAD D
MOV A,M
INX H
MOV H,M
MOV L,A
POP D
XTHL
RET
;
;
PORT0ST: ;CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT
IN STATUS
ANI 2
RZ
MVI A,0FFH
RET
;
;
PORT0IN: ;CONSOLE CHARACTER INTO REGISTER A
CALL PORT0ST
JZ PORT0IN
IN DATA
ANI 7FH ;STRIP PARITY BIT
RET
;
;
PORT0OUT: ;CONSOLE CHARACTER OUTPUT FROM REGISTER C
in status
rrc
jnc port0out
MOV A,C
OUT DATA
RET
;
;
PORT1ST:
IN STATUS1
ANI 2
RZ
MVI A,0FFH
RET
;
PORT1IN:
CALL PORT1ST
JZ PORT1IN
IN DATA1
ANI 7FH ;STRIP PARITY BIT
RET
;
PORT1OUT: ;LIST CHARACTER FROM REGISTER C
IN STATUS1
RRC
JNC PORT1OUT
MOV A,C ;CHARACTER TO REGISTER A
OUT DATA1
RET ;NULL SUBROUTINE
;
PORT2ST:
IN STATUS2
ANI 2
RZ
MVI A,0FFH
RET
;
PORT2IN:
CALL PORT2ST
JZ PORT2IN
IN DATA2
ANI 7FH
RET
;
PORT2OUT:
IN STATUS2
RRC
JNC PORT2OUT
MOV A,C
OUT DATA2
RET
;
;
PORTPOUT:
IN PARALLEL
ANI 80H
JNZ PORTPOUT
MOV A,C
OUTIT:
ORI 80H
OUT PARALLEL
ANI 7FH
OUT PARALLEL
ORI 80H
OUT PARALLEL
RET
;
;CP/M PHYSICAL DEVICE TO MICRO2 PHYSICAL DEVICE MAP
;
TTYST EQU PORT0ST
TTYIN EQU PORT0IN
TTYOUT EQU PORT0OUT
CRTST EQU PORT1ST
CRTIN EQU PORT1IN
CRTOUT EQU PORT1OUT
BATST EQU PORT2ST
BATIN EQU PORT2IN
BATOUT EQU PORT2OUT
UC1ST EQU PORT0ST
UC1IN EQU PORT0IN
UC1OUT EQU PORT0OUT
LPTOUT EQU PORTPOUT
UL1OUT EQU PORT2OUT
PTPOUT EQU PORT2OUT
PTRIN EQU PORT2IN
UP1OUT EQU PORT0OUT
UP2OUT EQU PORT1OUT
UR1IN EQU PORT0IN
UR2IN EQU PORT1IN
;
;
COMAND1 EQU 80H
STAT EQU 80H
HADDR EQU 81H
LADDR EQU 82H
COMAND2 EQU 83H
;
;
; I/O DRIVERS FOR THE DISK FOLLOW
;
HOME: ;MOVE TO THE TRACK O0 POSITION OF CURRENT DRIVE
CALL HEADLOAD
; H,L POINT TO WORD WITH TRACK FOR SELECTED DISK
HOMEL:
MVI M,00 ;SET CURRENT TRACK PTR BACK TO 0
IN STAT ;READ FDC STATUS
ANI 4 ;TEST TRACK 0 BIT
RZ ;RETURN IF AT 0
STC ;DIRECTION=OUT
CALL STEP ;STEP ONE TRACK
JMP HOMEL ;LOOP
;
SELDSK: ;SELECT DISK GIVEN BY REGISTER C
;MAKE SURE DUMMY IS 0 (FOR USE IN DOUBLE ADD TO H,L)
cpi ndisks ! jnc bad$drive
XRA A
STA DUMMY
MOV A,C
ANI 07H ;GET ONLY DISK SELECT BITS
STA DISKNO
MOV C,A
MOV B,A
;GET DENSITY OF SELECTED DRIVE
;B HAS DRIVE NUMBER FROM 0-7
LDA DENSITY
;DENSITY BIT 0= DENSITY FOR DRIVE A, BIT 1=DRIVE B ETC
;A 1 MEANS DOUBLE DENSITY
GETDR:
DCR B
RRC
JP GETDR ;NOT AT PROPER BIT YET
JC SETDOB
SETSING:
LXI D,SINGTAB
lxi h,stagger
JMP OVERBOTH
SETDOB:
LXI D,DOBTAB
lxi h,0 ; no stagger table
MOV A,C
;SET THE CHANGE DENSITY BIT
ORI 08
MOV C,A
OVERBOTH:
lda port ! ani 0f0h ! ora c ! sta port
push h ; save stagger table address
lhld diskno
dad h ! dad h ! dad h ! dad h
lxi b,dpbase+10
dad b ; points HL to right disk parameter table
mov m,e ! inx h ! mov m,d ; save diskdef address
lxi b,-10 ; point back to tran table address
dad b
pop d ; get current tran table
mov m,d ! dcx h ! mov m,e ; store its address
; HL now points to appropriate drive parameter block
RET
bad$drive: ; here if invalid drive code
lxi h,0 ! ret ; zero means select error
SETTRK: ;SET TRACK GIVEN BY REGISTER C
CALL HEADLOAD
;H,L REFERENCE CORRECT TRACK INDICATOR ACCORDING TO
;SELECTED DISK
MOV A,C ;DESIRED TRACK
CMP M
RZ ;WE ARE ALREADY ON THE TRACK
SETTKX:
CALL STEP ;STEP TRACK-CARRY HAS DIRECTION
;STEP WILL UPDATE TRACK INDICATOR
MOV A,C
CMP M ;ARE WE WHERE WE WANT TO BE
JNZ SETTKX ;NOT YET
;HAVE STEPPED ENOUGH
SEEKRT:
;DELAY 10 MSEC FOR FINAL STEP TIME AND HEAD SETTLE TIME
;THE DELAY ROUTINE DELAYS .5 MILLISECOND
MVI A,20D
CALL DELAY
RET ;END OF SETTRK ROUTINE
;
DELAY: ;ROUTINE TO DELAY C(A) .5 MILLISECONDS
PUSH B
DELAY2:
MVI C,086H ;ADJUST FOR .5 MSEC LOOP DELAY
;THIS IS THE VALUE FOR OUR IMSAI
LDXA:
DCR C
JNZ LDXA ;LOOP 1 MSEC
DCR A
JNZ DELAY2
POP B
RET ;END OF DELAY ROUTINE
;
sectran:
mov h,b ! mov l,c ! inx h ; in case we aren't using translation
mov a,d ! ora e ! rz ; we return logical+1
xchg ! dad b ! mov l,m ! mvi h,0 ; else fetch physical
ret ; back to bdos
SETSEC: ;SET SECTOR GIVEN BY REGISTER C
MOV A,C
STA SECTOR
RET
;
SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C
MOV L,C ;LOW ORDER ADDRESS
MOV H,B ;HIGH ORDER ADDRESS
SHLD DMAAD ;SAVE THE ADDRESS
RET
;
;
READ: ;PERFORM READ OPERATION.
;THIS IS SIMILAR TO WRITE, SO SET UP READ COMMAND AND USE
;COMMON CODE IN WRITE
MVI B,040H ;SET READ FLAG
JMP WAITIO ;TO PERFORM THE ACTUAL I/O
;
WRITE: ;PERFORM A WRITE OPERATION
MVI B,080H ;SET WRITE COMMAND
;
WAITIO:
;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O
;OPERATION. RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES
;PROPERLY, AND 01H IF AN ERROR OCCURS DURING THE READ OR WRITE
;
;IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO'
; THE TRACK NUMBER IN 'TRACK'
; THE SECTOR NUMBER IN 'SECTOR'
; THE DMA ADDRESS IN 'DMAAD'
;B STILL HAS R/W FLAG
MVI A,10D ;SET ERROR COUNT
STA ERRORS ;RETRY SOME FAILURES 10 TIMES
;BEFORE GIVING UP
TRYAGN:
PUSH B
CALL HEADLOAD
;H,L POINT TO TRACK BYTE FOR SELECTED DISK
POP B
MOV C,M
; DECIDE WHETHER TO ALLOW DISK WRITE PROCOMPENSTATION
MVI A,39D ;PRECOMP SHOULD BE INHIBITED ON TRACKS
;0-39
CMP C
JC ALLOWIT
;INHIBIT PRECOMP
MVI A,10H
ORA B
MOV B,A ;GOES OUT ON THE SAME PORT AS READ/WRITE
ALLOWIT:
LHLD DMAAD ;GET BUFFER ADDRESS
PUSH B ;B HAS R/W CODE C HAS TRACK
DCX H ;SAVE AND REPLACE 3 BYTES BELOW
;BUF WITH TRACK,SECTOR,ADDRESS MARK
MOV E,M
;FIGURE CORRECT ADDRESS MARK
LDA PORT
ANI 08H
MVI A,0FBH
JZ SIN
ANI 0FH ;WAS DOUBLE
;0BH IS DOUBLE DENSITY
;0FBH IS SINGLE DENSITY
SIN:
MOV M,A
;FILL IN SECTOR
DCX H
MOV D,M
LDA SECTOR ;NOTE THAT INVALID SECTOR NUMBER
;WILL RESULT IN HEAD UNLOADED
;ERROR, SO DONT CHECK
MOV M,A
;FILL IN TRACK
DCX H
POP B
MOV A,C
MOV C,M
MOV M,A
MOV A,H ;SET UP FDC DMA ADDRESS
OUT HADDR ;HIGH BYTE
MOV A,L
OUT LADDR ;LOW BYTE
MOV A,B ;GET R/W FLAG
OUT COMAND1 ;START DISK READ/WRITE
RWWAIT: IN STAT ;READ FDC STATUS
ANI 088H ;TEST FOR HEAD UNLOAD OR IOF
JZ RWWAIT
MOV M,C ;RESTORE 3 BYTES BELOW BUF
INX H
MOV M,D
INX H
MOV M,E
IN STAT ;TEST FOR ERRORS
ANI 0F0H
RZ ;A WILL BE 0 IF NO ERRORS
ERRTN:
;COME HERE ON ERROR FROM DISK
PUSH PSW ;SAVE ERROR CONDITION
;CHECK FOR 10 ERRORS
LXI H,ERRORS
DCR M
JNZ REDO ;NOT TEN YET. DO A RETRY
;WE HAVE TOO MANY ERRORS. PRINT OUT HEX NUMBER FOR LAST
;RECEIVED ERROR TYPE. CPM WILL PRINT PERM ERROR MESSAGE.
POP PSW ;GET CODE
RRC
RRC
RRC
RRC
;MAKE IT ASCII
ORI 030H
STA BDOS+0A4H
;SET ERROR RETURN FOR OPERATING SYSTEM
MVI A,1
RET
REDO:
;B STILL HAS READ/WRITE FLAG
POP PSW ;GET ERROR CODE
ANI 0E0H ;RETRY IF NOT TRACK ERROR
JNZ TRYAGN ;
;WAS A TRACK ERROR SO NEED TO RESEEK
PUSH B ;SAVE READ/WRITE INDICATOR
;FIGURE OUT THE DESIRED TRACK
LXI D,TRACK
LHLD DISKNO ;SELECTED DISK
DAD D ;POINT TO CORRECT TRACK INDICATOR
MOV A,M ;DESIRED TRACK
PUSH PSW ;SAVE IT
CALL HOME
POP PSW
MOV C,A
CALL SETTRK
POP B ;GET READ/WRITE INDICATOR
JMP TRYAGN
;
;
;
STEP: ;STEP HEAD OUT TOWARDS ZERO
;IF CARRY IS SET; ELSE
;STEP IN
; H,L POINT TO CORRECT TRACK INDICATOR WORD
JC OUTX
INR M ;INCREMENT CURRENT TRACK BYTE
MVI A,04H ;SET DIRECTION = IN
DOSTEP:
ORI 2
OUT COMAND1 ;PULSE STEP BIT
ANI 0FDH
OUT COMAND1 ;TURN OFF PULSE
;THE FDC-2 HAD A STEPP READY LINE. THE FDC-3 RELIES ON
;SOFTWARE TIME OUT
MVI A,16D ;WAIT FOR STEP READY
;DELAY ROUTINE DELAYS FOR .5 MSEC TIMES THE CONTENTS OF REG A
CALL DELAY
RET
;
OUTX:
DCR M ;UPDATE TRACK BYTE
XRA A
JMP DOSTEP
;
HEADLOAD:
;SELECT AND LOAD THE HEAD ON THE CORRECT DRIVE
LXI H,PORTOUT ;OLD SLECT INFO
MOV B,M
DCX H ;NEW SELECT INFO
MOV A,M
INX H
MOV M,A
OUT COMAND2 ;SELECT THE DRIVE
;SET UP H.L TO POINT TO TRACK BYTE FOR SELECTED DISK
LXI D,TRACK
LHLD DISKNO
DAD D
;NOW CHECK FOR NEEDING A 35 MS DELAY
;IF WE HAVE CHANGED DRIVES OR IF THE HEAD IS UNLOADED
;WE NEED0TO WAIT 35 MS FOR HEAD SETTLE
CMP B ;ARE WE ON THE SAME DRIVE AS BEFORE
JNZ NEEDDLY
;WE ARE ON THE SAME DRIVE
;IS THE HEAD LOADED?
IN STAT
ANI 80H
RZ ;ALREADY LOADED
NEEDDLY:
XRA A
OUT COMAND1 ;LOAD THE HEAD
;THE DELAY ROUTINE DELAYS FOR .5 MSEC
MVI A,70D
CALL DELAY
RET
;
; disks 2
dpbase:
dpe0: dw $-$, 0
dw 0, 0
dw dirbuf, $-$
dw csv0, alv0
dpe1: dw $-$, 0
dw 0, 0
dw dirbuf, $-$
dw csv1, alv1
dobtab:
; diskdef 0,1,58,,2048,256,128,128,2
dw 58
db 4,15
if ldr
db 0
else
db 1
endif
dw 255,127
db 192,0
dw 32,2
singtab:
; diskdef 1,1,26,6,1024,243,64,64,2
dw 26
db 3,7,0
dw 242,63
db 192,0
dw 16,2
stagger: ; Standard CP/M Stagger Table (Skew 6)
db 1,7,13,19,25
db 5,11,17,23
db 3,9,15,21
db 2,8,14,20,26
db 6,12,18,24
db 4,10,16,22
; endef
begdat:
dirbuf:
ds 128
alv0:
ds 32
csv0:
ds 32
alv1:
ds 32
csv1:
ds 32
enddat equ $
end


View File

@@ -0,0 +1,96 @@
; MDS-800 Cold Start Loader for MP/M 1.1
;
; VERSION 1.1 JANUARY, 1980
;
mpmldrb equ 0100h ;base of MP/M loader
;
org 3000h ;loaded here by hardware
;
ntrks equ 2 ;tracks to read
mpmldr0 equ 25 ;# on track 0
mpmldr1 equ 26 ;# on track 1
;
rmon80 equ 0ff0fh ;restart location for mon80
base equ 078h ;'base' used by controller
rtype equ base+1 ;result type
rbyte equ base+3 ;result byte
reset equ base+7 ;reset controller
;
dstat equ base ;disk status port
ilow equ base+1 ;low iopb address
ihigh equ base+2 ;high iopb address
bsw equ 0ffh ;boot switch
readf equ 4h ;disk read function
stack equ 100h ;use end of boot for stack
;
rstart:
lxi sp,stack;in case of call to mon80
; clear disk status
in rtype
in rbyte
; check if boot switch is off
coldstart:
in bsw
ani 02h ;switch on?
jnz coldstart
; clear the controller
out reset ;logic cleared
;
;
mvi b,ntrks ;number of tracks to read
lxi h,iopb0
;
start:
;
; read first/next track into cpmb
mov a,l
out ilow
mov a,h
out ihigh
wait0: in dstat
ani 4
jz wait0
;
; check disk status
in rtype
ani 11b
cpi 2
;
jnc rstart ;retry the load
;
in rbyte ;i/o complete, check status
; if not ready, then go to mon80
ral
cc rmon80 ;not ready bit set
rar ;restore
ani 11110b ;overrun/addr err/seek/crc/xxxx
;
jnz rstart ;retry the load
;
;
lxi d,iopbl ;length of iopb
dad d ;addressing next iopb
dcr b ;count down tracks
jnz start
;
;
; jmp to the MP/M loader
jmp mpmldrb
;
; parameter blocks
iopb0: db 80h ;iocw, no update
db readf ;read function
db mpmldr0 ;# sectors to read trk 0
db 0 ;track 0
db 2 ;start with sector 2, trk 0
dw mpmldrb ;start at base of bdos
iopbl equ $-iopb0
;
iopb1: db 80h
db readf
db mpmldr1 ;sectors to read on track 1
db 1 ;track 1
db 1 ;sector 1
dw mpmldrb+mpmldr0*128 ;base of second read
end


View File

@@ -0,0 +1,7 @@
:10300000310001DB79DB7BDBFFE602C20730D37FD7
:1030100006022142307DD3797CD37ADB78E604CA7C
:103020001B30DB79E603FE02D20030DB7B17DC0FBE
:10303000FF1FE61EC200301107001905C21530C37C
:1030400000018004190002000180041A0101800DB2
:0000000000


View File

@@ -0,0 +1,417 @@
; MDS I/O drivers for CP/M 2.0
; (single drive, single density)
; -or-
; (single drive, double density)
; MP/M 1.0 Loader BIOS
; (modified CP/M 2.0 BIOS)
; Version 1.0 -- Sept 79
vers equ 20 ;version 2.0
; Copyright (C) 1978, 1979
; Digital Research
; Box 579, Pacific Grove
; California, 93950
false equ 0
true equ not false
asm equ true
mac equ not asm
sgl equ true
dbl equ not sgl
if mac
maclib diskdef
numdsks equ 1 ;number of drives available
endif
ram$top equ 1d00h ; top address+1
bios equ ram$top-0600h ; basic input/output system
bdos equ bios-0e00h ; base of the bdos
org bios
buff equ 0080h ;default buffer address
retry equ 10 ;max retries on disk i/o before error
; jump vector for indiviual routines
jmp boot
wboote: jmp wboot
jmp const
jmp conin
jmp conout
jmp list
jmp punch
jmp reader
jmp home
jmp seldsk
jmp settrk
jmp setsec
jmp setdma
jmp read
jmp write
jmp list$st ; list status poll
jmp sect$tran ; sector translation
; we also assume the MDS system has four disk drives
numdisks equ 1 ;number of drives available
revrt equ 0fdh ;interrupt revert port
intc equ 0fch ;interrupt mask port
icon equ 0f3h ;interrupt control port
inte equ 0111$1110b ;enable rst 0(warm boot), rst 7 (monitor)
; MDS monitor equates
rmon80 equ 0ff0fh ;restart mon80 (boot error)
; disk ports and commands
base equ 78h ;base of disk command io ports
dstat equ base ;disk status (input)
rtype equ base+1 ;result type (input)
rbyte equ base+3 ;result byte (input)
ilow equ base+1 ;iopb low address (output)
ihigh equ base+2 ;iopb high address (output)
readf equ 4h ;read function
writf equ 6h ;write function
recal equ 3h ;recalibrate drive
iordy equ 4h ;i/o finished mask
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
boot:
wboot:
gocpm:
ret
crtin: ; crt: input
in 0f7h ! ani 2 ! jz crtin
in 0f6h ! ani 7fh
ret
crtout: ; crt: output
in 0f7h ! ani 1 ! jz crtout
mov a,c ! out 0f6h
ret
crtst: ; crt: status
in 0f7h ! ani 2 ! rz
ori 0ffh
ret
ttyin: ; tty: input
in 0f5h ! ani 2 ! jz ttyin
in 0f4h ! ani 7fh
ret
ttyout: ; tty: output
in 0f5h ! ani 1 ! jz ttyout
mov a,c ! out 0f4h
ret
;ttyst:
; in 0f5h ! ani 2 ! rz
; ori -1
; ret
lptout: ; lpt: output
in 0fbh ! ani 1 ! jz lptout
mov a,c ! cma ! out 0fah
ret
lpt$st:
in 0fbh ! ani 1 ! rz
ori 0ffh
ret
conin equ crtin
const equ crtst
conout equ crtout
reader equ ttyin
punch equ ttyout
list equ lptout
listst equ lptst
seldsk: ;select disk given by register c
lxi h, 0 ! mov a,c ! cpi num$disks ! rnc ; first, insure good select
ani 2 ! sta dbank ; then save it
lxi h,sel$table ! mvi b,0 ! dad b ! mov a,m ! sta iof
mov h,b ! mov l,c
dad h ! dad h ! dad h ! dad h ; times 16
lxi d,dpbase ! dad d
ret
home: ;move to home position
; treat as track 00 seek
mvi c,0
;
settrk: ;set track address given by c
lxi h,iot
mov m,c
ret
;
setsec: ;set sector number given by c
mov a,c ;sector number to accum
sta ios ;store sector number to iopb
ret
;
setdma: ;set dma address given by regs b,c
mov l,c
mov h,b
shld iod
ret
sect$tran: ; translate the sector # in <c> if needed
mov h,b ! mov l,c ! inx h ; in case of no translation
mov a, d ! ora e ! rz
xchg ! dad b ; point to physical sector
mov l,m ! mvi h,0
ret
read: ;read next disk record (assuming disk/trk/sec/dma set)
mvi c,readf ;set to read function
jmp setfunc
;
write: ;disk write function
mvi c,writf
;
setfunc:
; set function for next i/o (command in reg-c)
lxi h,iof ;io function address
mov a,m ;get it to accumulator for masking
ani 1111$1000b ;remove previous command
ora c ;set to new command
mov m,a ;replaced in iopb
; single density drive 1 requires bit 5 on in sector #
; mask the bit from the current i/o function
ani 0010$0000b ;mask the disk select bit
lxi h,ios ;address the sector select byte
ora m ;select proper disk bank
mov m,a ;set disk select bit on/off
;
waitio:
mvi c,retry ;max retries before perm error
rewait:
; start the i/o function and wait for completion
call intype ;in rtype
call inbyte ;clears the controller
lda dbank ;set bank flags
ora a ;zero if drive 0,1 and nz if 2,3
mvi a,iopb and 0ffh ;low address for iopb
mvi b,iopb shr 8 ;high address for iopb
jnz iodr1 ;drive bank 1?
out ilow ;low address to controller
mov a,b
out ihigh ;high address
jmp wait0 ;to wait for complete
iodr1: ;drive bank 1
out ilow+10h ;88 for drive bank 10
mov a,b
out ihigh+10h
wait0: call instat ;wait for completion
ani iordy ;ready?
jz wait0
; check io completion ok
call intype ;must be io complete (00) unlinked
; 00 unlinked i/o complete, 01 linked i/o complete (not used)
; 10 disk status changed 11 (not used)
cpi 10b ;ready status change?
jz wready
; must be 00 in the accumulator
ora a
jnz werror ;some other condition, retry
; check i/o error bits
call inbyte
ral
jc wready ;unit not ready
rar
ani 11111110b ;any other errors? (deleted data ok)
jnz werror
; read or write is ok, accumulator contains zero
ret
wready: ;not ready, treat as error for now
call inbyte ;clear result byte
jmp trycount
werror: ;return hardware malfunction (crc, track, seek, etc.)
; the MDS controller has returned a bit in each position
; of the accumulator, corresponding to the conditions:
; 0 - deleted data (accepted as ok above)
; 1 - crc error
; 2 - seek error
; 3 - address error (hardware malfunction)
; 4 - data over/under flow (hardware malfunction)
; 5 - write protect (treated as not ready)
; 6 - write error (hardware malfunction)
; 7 - not ready
; (accumulator bits are numbered 7 6 5 4 3 2 1 0)
trycount:
; register c contains retry count, decrement 'til zero
dcr c
jnz rewait ;for another try
; cannot recover from error
mvi a,1 ;error code
ret
; intype, inbyte, instat read drive bank 00 or 10
intype: lda dbank
ora a
jnz intyp1 ;skip to bank 10
in rtype
ret
intyp1: in rtype+10h ;78 for 0,1 88 for 2,3
ret
inbyte: lda dbank
ora a
jnz inbyt1
in rbyte
ret
inbyt1: in rbyte+10h
ret
instat: lda dbank
ora a
jnz insta1
in dstat
ret
insta1: in dstat+10h
ret
; utility subroutines
prmsg: ;print message at h,l to 0
mov a,m ! ora a ! rz
push h ! mov c,a ! call conout ! pop h
inx h ! jmp prmsg
; data areas (must be in ram)
dbank: db 0 ;disk bank 00 if drive 0,1
; 10 if drive 2,3
iopb: ;io parameter block
db 80h ;normal i/o operation
iof: db readf ;io function, initial read
ion: db 1 ;number of sectors to read
iot: db 2 ;track number
ios: db 1 ;sector number
iod: dw buff ;io address
;
;
sel$table:
if sgl
db 00h, 30h, 00h, 30h ; drive select bits
endif
if dbl
db 00h, 10h, 00h, 30h ; drive select bits
endif
if mac and sgl
disks numdisks ; generate drive tables
diskdef 0,1,26,6,1024,243,64,64,2
endef
endif
if mac and dbl
disks numdisks ; generate drive tables
diskdef 0,1,52,,2048,243,128,128,2,0
endef
endif
if asm
dpbase equ $ ;base of disk param blks
dpe0: dw xlt0,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb0 ;dir buff, parm block
dw csv0,alv0 ;check, alloc vectors
dpb0 equ $ ;disk param block
endif
if asm and sgl
dw 26 ;sec per track
db 3 ;block shift
db 7 ;block mask
db 0 ;extnt mask
dw 242 ;disk size-1
dw 63 ;directory max
db 192 ;alloc0
db 0 ;alloc1
dw 16 ;check size
dw 2 ;offset
xlt0 equ $ ;translate table
db 1
db 7
db 13
db 19
db 25
db 5
db 11
db 17
db 23
db 3
db 9
db 15
db 21
db 2
db 8
db 14
db 20
db 26
db 6
db 12
db 18
db 24
db 4
db 10
db 16
db 22
endif
if asm and dbl
xlt0 equ 0
endif
if asm
begdat equ $
dirbuf: ds 128 ;directory access buffer
alv0: ds 31
csv0: ds 16
endif
if asm and dbl
ds 16
endif
if asm
enddat equ $
datsiz equ $-begdat
endif
end


View File

@@ -0,0 +1,882 @@
;
; Note: this module assumes that an ORG statement will be
; provided by concatenating either BASE0000.ASM or BASE0100.ASM
; to the front of this file before assembling.
;
; title 'Xios for the MDS-800'
; (four drive single density version)
; -or-
; (four drive mixed double/single density)
; Version 1.1X November, 1979
; Copyright (C) 1979
; Digital Research
; Box 579, Pacific Grove
; California, 93950
false equ 0
true equ not false
asm equ true
mac equ not asm
sgl equ true
dbl equ not sgl
if mac
maclib diskdef
endif
numdisks equ 4 ;number of drives available
; external jump table (below xios base)
pdisp equ $-3
xdos equ pdisp-3
; mds interrupt controller equates
revrt equ 0fdh ; revert port
intc equ 0fch ; mask port
icon equ 0f3h ; control port
rtc equ 0ffh ; real time clock
inte equ 1111$1101b ; enable rst 1
; mds disk controller equates
dskbase equ 78h ; base of disk io prts
dstat equ dskbase ; disk status
rtype equ dskbase+1 ; result type
rbyte equ dskbase+3 ; result byte
ilow equ dskbase+1 ; iopb low address
ihigh equ dskbase+2 ; iopb high address
readf equ 4h ; read function
writf equ 6h ; write function
iordy equ 4h ; i/o finished mask
retry equ 10 ; max retries on disk i/o
; basic i/o system jump vector
jmp coldstart ;cold start
wboot:
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 home ;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 sect$tran ;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
jmp saveZ80 ; save extra Z80 registers
jmp restoreZ80 ; restore extra Z80 registers
jmp idle ; idle procedure
coldstart:
warmstart:
mvi c,0 ; see system init
; cold & warm start included only
; for compatibility with cp/m
jmp xdos ; system reset, terminate process
; MP/M 1.0 console handlers
nmbcns equ 2 ; number of consoles
poll equ 131 ; xdos poll function
pllpt equ 0 ; poll printer
pldsk equ 1 ; poll disk
plco0 equ 2 ; poll console out #0 (CRT:)
plco1 equ 3 ; poll console out #1 (TTY:)
plci0 equ 4 ; poll console in #0 (CRT:)
plci1 equ 5 ; poll console in #1 (TTY:)
;
const: ; console status
call ptbljmp ; compute and jump to hndlr
dw pt0st ; console #0 status routine
dw pt1st ; console #1 (TTY:) status rt
conin: ; console input
call ptbljmp ; compute and jump to hndlr
dw pt0in ; console #0 input
dw pt1in ; console #1 (TTY:) input
conout: ; console output
call ptbljmp ; compute and jump to hndlr
dw pt0out ; console #0 output
dw pt1out ; console #1 (TTY:) 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
rtnempty:
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
; ascii character equates
rubout equ 7fh
space equ 20h
; serial i/o port address equates
data0 equ 0f6h
sts0 equ data0+1
data1 equ 0f4h
sts1 equ data1+1
lptport equ 0fah
lptsts equ lptport+1
; poll console #0 input
polci0:
pt0st: ; return 0ffh if ready,
; 000h if not
in sts0
ani 2
rz
mvi a,0ffh
ret
;
; console #0 input
;
pt0in: ; return character in reg a
mvi c,poll
mvi e,plci0
call xdos ; poll console #0 input
in data0 ; read character
ani 7fh ; strip parity bit
ret
;
; console #0 output
;
pt0out: ; reg c = character to output
push b
call pt0wait ; poll console #0 output
pop b
mov a,c
out data0 ; transmit character
ret
;
; wait for console #0 output ready
;
pt0wait:
mvi c,poll
mvi e,plco0
jmp xdos ; poll console #0 output
; ret
;
; poll console #0 output
;
polco0:
; return 0ffh if ready,
; 000h if not
in sts0
ani 01h
rz
mvi a,0ffh
ret
;
;
; line printer driver:
;
list: ; list output
push b
push d
mvi c, poll
mvi e, pllpt
call xdos
pop d
pop b
mov a,c
cma
out lptport
ret
;
; poll printer output
;
pollpt:
; return 0ffh if ready,
; 000h if not
in lptsts
ani 01h
rz
mvi a,0ffh
ret
;
; poll console #1 (TTY:) input
;
polci1:
pt1st:
; return 0ffh if ready,
; 000h if not
in sts1
ani 2
rz
mvi a,0ffh
ret
;
; console #1 (TTY:) input
;
pt1in:
; return character in reg a
mvi c,poll
mvi e,plci1
call xdos ; poll console #1 input
in data1 ; read character
ani 7fh ; strip parity bit
ret
;
; console #1 (TTY:) output
;
pt1out:
; reg c = character to output
push b
call pt1wait
pop b
mov a,c
out data1 ; transmit character
ret
; wait for console #1 (TTY:) output ready
pt1wait:
mvi c,poll
mvi e,plco1
jmp xdos ; poll console #1 output
; ret
; poll console #1 (TTY:) output
polco1:
; return 0ffh if ready,
; 000h if not
in sts1
ani 01h
rz
mvi a,0ffh
ret
;
;
; MP/M 1.0 extended i/o system
;
;
nmbdev equ 6 ; number of devices in poll tbl
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
dw pollpt ; poll printer output
dw poldsk ; poll disk ready
dw polco0 ; poll console #0 output
dw polco1 ; poll console #1 (TTY:) output
dw polci0 ; poll console #0 input
dw polci1 ; poll console #1 (TTY:) input
dw rtnempty; bad device handler
; select / protect memory
selmemory:
; reg bc = adr of mem descriptor
; bc -> base 1 byte,
; size 1 byte,
; attrib 1 byte,
; bank 1 byte.
; this hardware does not have memory protection or
; bank switching
ret
; 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
; system initialization
systeminit:
; note: this system init assumes that the usarts
; have been initialized by the coldstart boot
; setup restart jump vectors
mvi a,0c3h
sta 1*8
lxi h,int1hnd
shld 1*8+1 ; jmp int1hnd at restart 1
; setup interrupt controller & real time clock
mvi a,inte
out intc ; enable int 0,1,7
xra a
out icon ; clear int mask
out rtc ; enable real time clock
ret
;
; Z80 extra register save and restore
;
saveZ80:
pop h ; return address to HL
; push IX, IY, etc.
pchl
restoreZ80:
; pop IX, IY, etc.
ret
;
; Idle procedure
;
idle:
mvi c,dsptch
jmp xdos ; perform a dispatch, this form
; of idle must be used in systems
; without interrupts, i.e. all polled
; -or-
; ei ; simply halt until awaken by an
; hlt ; interrupt
; ret
; MP/M 1.0 interrupt handlers
flagset equ 133
dsptch equ 142
int1hnd:
; interrupt 1 handler entry point
;
; location 0008h contains a jmp
; to int1hnd.
push psw
mvi a,2h
out rtc ; reset real time clock
out revrt ; revert intr cntlr
lda slice
dcr a ; only service every 32nd slice
sta slice
jz t32ms ; jump if 32ms elapsed
pop psw
ei
ret
t32ms:
mvi a,32
sta slice ; reset slice counter
pop psw
shld svdhl
pop h
shld svdret
push psw
lxi h,0
dad sp
shld svdsp ; save users stk ptr
lxi sp,intstk+48 ; lcl stk for intr hndl
push d
push b
mvi a,0ffh
sta preemp ; set preempted flag
lda tickn
ora a ; test tickn, indicates
; delayed process(es)
jz notickn
mvi c,flagset
mvi e,1
call xdos ; set flag #1 each tick
notickn:
lxi h,cnt32
dcr m ; dec 32 tick cntr
jnz not1sec
mvi m,32
mvi c,flagset
mvi e,2
call xdos ; set flag #2 @ 1 sec
not1sec:
xra a
sta preemp ; clear preempted flag
pop b
pop d
lhld svdsp
sphl ; restore stk ptr
pop psw
lhld svdret
push h
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.
jmp pdisp ; MP/M dispatch
;
; bios data segment
;
slice: db 32 ; 32 slices = 32ms = 1 tick
cnt32: db 32 ; 32 tick cntr = 1 sec
intstk: ds 48 ; local intrpt stk
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
;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Intel MDS-800 diskette interface routines *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
seldsk: ;select disk given by register c
lxi h, 0
mov a,c
cpi numdisks
rnc ; first, insure good select
ani 2
sta dbank ; then save it
lxi h,sel$table
mvi b,0
dad b
mov a,m
sta iof
mov h,b
mov l,c
dad h
dad h
dad h
dad h ; times 16
lxi d,dpbase
dad d
ret
home: ;move to home position
; treat as track 00 seek
mvi c,0
;
settrk: ;set track address given by c
lxi h,iot
mov m,c
ret
;
setsec: ;set sector number given by c
mov a,c ;sector number to accum
sta ios ;store sector number to iopb
ret
;
setdma: ;set dma address given by regs b,c
mov l,c
mov h,b
shld iod
ret
sect$tran: ; translate the sector # in <c> if needed
mov h,b
mov l,c
inx h ; in case of no translation
mov a, d
ora e
rz
xchg
dad b ; point to physical sector
mov l,m
mvi h,0
ret
read: ;read next disk record (assuming disk/trk/sec/dma set)
mvi c,readf ;set to read function
jmp setfunc
;
write: ;disk write function
mvi c,writf
;
setfunc:
; set function for next i/o (command in reg-c)
lxi h,iof ;io function address
mov a,m ;get it to accumulator for masking
ani 1111$1000b ;remove previous command
ora c ;set to new command
mov m,a ;replaced in iopb
; single density drive 1 requires bit 5 on in sector #
; mask the bit from the current i/o function
ani 0010$0000b ;mask the disk select bit
lxi h,ios ;address the sector select byte
ora m ;select proper disk bank
mov m,a ;set disk select bit on/off
;
waitio:
mvi c,retry ;max retries before perm error
rewait:
; start the i/o function and wait for completion
call intype ;in rtype
call inbyte ;clears the controller
lda dbank ;set bank flags
ora a ;zero if drive 0,1 and nz if 2,3
mvi a,iopb and 0ffh ;low address for iopb
mvi b,iopb shr 8 ;high address for iopb
jnz iodr1 ;drive bank 1?
out ilow ;low address to controller
mov a,b
out ihigh ;high address
jmp wait0 ;to wait for complete
iodr1: ;drive bank 1
out ilow+10h ;88 for drive bank 10
mov a,b
out ihigh+10h
wait0:
push b ; save retry count
mvi c, poll ; function poll
mvi e, pldsk ; device is disk
call xdos
pop b ; restore retry counter in <c>
; check io completion ok
call intype ;must be io complete (00) unlinked
; 00 unlinked i/o complete, 01 linked i/o complete (not used)
; 10 disk status changed 11 (not used)
cpi 10b ;ready status change?
jz wready
; must be 00 in the accumulator
ora a
jnz werror ;some other condition, retry
; check i/o error bits
call inbyte
ral
jc wready ;unit not ready
rar
ani 11111110b ;any other errors? (deleted data ok)
jnz werror
; read or write is ok, accumulator contains zero
ret
poldsk:
call instat ; get current controller status
ani iordy ; operation complete ?
rz ; not done
mvi a,0ffh ; done flag
ret ; to xdos
wready: ;not ready, treat as error for now
call inbyte ;clear result byte
jmp trycount
werror: ;return hardware malfunction (crc, track, seek, etc.)
; the mds controller has returned a bit in each position
; of the accumulator, corresponding to the conditions:
; 0 - deleted data (accepted as ok above)
; 1 - crc error
; 2 - seek error
; 3 - address error (hardware malfunction)
; 4 - data over/under flow (hardware malfunction)
; 5 - write protect (treated as not ready)
; 6 - write error (hardware malfunction)
; 7 - not ready
; (accumulator bits are numbered 7 6 5 4 3 2 1 0)
trycount:
; register c contains retry count, decrement 'til zero
dcr c
jnz rewait ;for another try
; cannot recover from error
mvi a,1 ;error code
ret
; intype, inbyte, instat read drive bank 00 or 10
intype: lda dbank
ora a
jnz intyp1 ;skip to bank 10
in rtype
ret
intyp1: in rtype+10h ;78 for 0,1 88 for 2,3
ret
inbyte: lda dbank
ora a
jnz inbyt1
in rbyte
ret
inbyt1: in rbyte+10h
ret
instat: lda dbank
ora a
jnz insta1
in dstat
ret
insta1: in dstat+10h
ret
; data areas (must be in ram)
dbank: db 0 ;disk bank 00 if drive 0,1
; 10 if drive 2,3
iopb: ;io parameter block
db 80h ;normal i/o operation
iof: db readf ;io function, initial read
ion: db 1 ;number of sectors to read
iot: db 2 ;track number
ios: db 1 ;sector number
iod: dw $-$ ;io address
sel$table:
if sgl
db 00h, 30h, 00h, 30h ; drive select bits
endif
if dbl
db 00h, 10h, 00h, 30h ; drive select bits
endif
if mac and sgl
disks numdisks ; generate drive tables
diskdef 0,1,26,6,1024,243,64,64,2
diskdef 1,0
diskdef 2,0
diskdef 3,0
endef
endif
if mac and dbl
disks numdisks ; generate drive tables
diskdef 0,1,52,,2048,243,128,128,2,0
diskdef 1,0
diskdef 2,1,26,6,1024,243,64,64,2
diskdef 3,2
endef
endif
if asm
dpbase equ $ ;base of disk param blks
dpe0: dw xlt0,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb0 ;dir buff, parm block
dw csv0,alv0 ;check, alloc vectors
dpe1: dw xlt1,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb1 ;dir buff, parm block
dw csv1,alv1 ;check, alloc vectors
dpe2: dw xlt2,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb2 ;dir buff, parm block
dw csv2,alv2 ;check, alloc vectors
dpe3: dw xlt3,0000h ;translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpb3 ;dir buff, parm block
dw csv3,alv3 ;check, alloc vectors
dpb0 equ $ ;disk param block
endif
if asm and dbl
dw 52 ;sec per track
db 4 ;block shift
db 15 ;block mask
db 0 ;extnt mask
dw 242 ;disk size-1
dw 127 ;directory max
db 192 ;alloc0
db 0 ;alloc1
dw 32 ;check size
dw 2 ;offset
xlt0 equ 0 ;translate table
dpb1 equ dpb0
xlt1 equ xlt0
dpb2 equ $
endif
if asm
dw 26 ;sec per track
db 3 ;block shift
db 7 ;block mask
db 0 ;extnt mask
dw 242 ;disk size-1
dw 63 ;directory max
db 192 ;alloc0
db 0 ;alloc1
dw 16 ;check size
dw 2 ;offset
endif
if asm and sgl
xlt0 equ $
endif
if asm and dbl
xlt2 equ $
endif
if asm
db 1
db 7
db 13
db 19
db 25
db 5
db 11
db 17
db 23
db 3
db 9
db 15
db 21
db 2
db 8
db 14
db 20
db 26
db 6
db 12
db 18
db 24
db 4
db 10
db 16
db 22
endif
if asm and sgl
dpb1 equ dpb0
xlt1 equ xlt0
dpb2 equ dpb0
xlt2 equ xlt0
dpb3 equ dpb0
xlt3 equ xlt0
endif
if asm and dbl
dpb3 equ dpb2
xlt3 equ xlt2
endif
if asm
begdat equ $
dirbuf: ds 128 ;directory access buffer
endif
if asm and sgl
alv0: ds 31
csv0: ds 16
alv1: ds 31
csv1: ds 16
endif
if asm and dbl
alv0: ds 31
csv0: ds 32
alv1: ds 31
csv1: ds 32
endif
if asm
alv2: ds 31
csv2: ds 16
alv3: ds 31
csv3: ds 16
enddat equ $
datsiz equ $-begdat
endif
db 0 ; this last db is req'd to
; ensure that the hex file
; output includes the entire
; diskdef
end


Binary file not shown.

View File

@@ -0,0 +1,138 @@
;WARM START LOADER FOR DOUBLE DENSITY
;VERSION M4.1
;INTERRUPTS ARE NOT IMPLEMENTED
;THIS IS STORED IN TRACK 0 SECTOR 2
;AND IS LOADED INTO THE 80 BYTES BELOW THE OP SYSTEM ON A
;COLD OR WARM BOOT
;
;
;THIS VERSION CONTAINS DISK DRIVERS FOR THE DIGITAL SYSTEMS
;FDC-3 CONTROLLER BOARD. THIS BOARD CAN HANDLE DOUBLE DENSITY
;
; NOTE : MSIZE DETERMINES WHERE THIS CBIOS IS LOCATED
MSIZE EQU 64 ;CP/M VERSION MEMORY SIZE IN KILOBYTES
;
;
ram$top equ msize*1024
BIOS EQU ram$top-6*256 ;START OF THE CBIOS PATCH
BDOS EQU bios-0e00h ;BASE OF RESIDENT PORTION OF CP/M
ccp EQU bdos-0800h ;LENGTH OF THE CP/M SYSTEM IN BYTES
warmboot equ ccp-0080h
NSECTS EQU (bios-ccp)/128 ;NUMBER OF SECTORS TO LOAD ON WARM START
;
ORG warm$boot ;ORIGIN OF THIS PROGRAM
WBOTE EQU BIOS+3
SETSEC EQU BIOS+21H
SETTRK EQU BIOS+1EH
SETDMA EQU BIOS+24H
READ EQU BIOS+27H
CONOUT EQU BIOS+0CH
SIGNON EQU BIOS+33h
;
PORT EQU 04AH
DENSITY EQU 04CH
;
; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
JMP INITIO ;COLD START
;
;
WBOOT: ;SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED
;
;
MVI B,NSECTS ;B COUNTS THE NUMBER OF SECTORS TO LOAD
MVI C,0 ;C HAS THE CURRENT TRACK NUMBER
MVI D,3 ;D HAS THE NEXT SECTOR TO READ
; NOTE THAT WE BEGIN BY READING TRACK 0, SECTOR 3 SINCE SECTOR 1
; CONTAINS THE COLD START LOADER, WHICH IS SKIPPED IN A WARM START
; AND SECTOR 2 IS THE WARM START LOADER
LXI H,CCP ;BASE OF CP/M (INITIAL LOAD POINT)
LOAD1: ;LOAD ONE MORE SECTOR
PUSH B ;SAVE SECTOR COUNT, CURRENT TRACK
PUSH D ;SAVE NEXT SECTOR TO READ
PUSH H ;SAVE DMA ADDRESS
MOV C,D ;GET SECTOR ADDRESS TO REGISTER C
CALL SETSEC ;SET SECTOR ADDRESS FROM REGISTER C
POP B ;RECALL DMA ADDRESS TO B,C
PUSH B ;REPLACE ON STACK FOR LATER RECALL
CALL SETDMA ;SET DMA ADDRESS FROM B,C
;
; DRIVE SET TO 0, TRACK SET, SECTOR SET, DMA ADDRESS SET
CALL READ
ORA A ;ANY ERRORS?
JNZ WBOOT ;RETRY THE ENTIRE BOOT IF AN ERROR OCCURS
;
; NO ERROR, MOVE TO NEXT SECTOR
POP H ;RECALL DMA ADDRESS
LXI D,128 ;DMA=DMA+128
DAD D ;NEW DMA ADDRESS IS IN H,L
POP D ;RECALL SECTOR ADDRESS
POP B ;RECALL NUMBER OF SECTORS REMAINING, AND CURRENT TRK
DCR B ;SECTORS=SECTORS-1
JZ GOCPM ;TRANSFER TO CP/M IF ALL HAVE BEEN LOADED
;
; MORE SECTORS REMAIN TO LOAD, CHECK FOR TRACK CHANGE
INR D
MOV A,D ;SECTOR=27?, IF SO, CHANGE TRACKS
CPI 27
JC LOAD1 ;CARRY GENERATED IF SECTOR<27
;
; END OF CURRENT TRACK, GO TO NEXT TRACK
;CHECK FOR DENSITY CHANGE
;THE DENSITY TO BE USED IS THE DENSITY OF DRIVE A
LDA DENSITY
RRC
JNC LOAD2
;CHANGE TO DOUBLE DENSITY
MVI A,8
STA PORT
LOAD2:
MVI D,1 ;BEGIN WITH FIRST SECTOR OF NEXT TRACK
INR C ;TRACK=TRACK+1
;
; SAVE REGISTER STATE, AND CHANGE TRACKS
PUSH B
PUSH D
PUSH H
CALL SETTRK ;TRACK ADDRESS SET FROM REGISTER C
POP H
POP D
POP B
JMP LOAD1 ;FOR ANOTHER SECTOR
;
INITIO:
;
;GIVE LOG-ON MESSAGE ON COLD START ONLY
LXI SP,80H
LXI H,SIGNON
PRTMESS:
MOV A,M
ORA A ;ZERO?
JZ GOCPM
PUSH H
MOV C,A
CALL CONOUT
POP H
INX H
JMP PRTMESS
GOCPM:
;COME HERE ON EITHER WARM OR COLD BOOT
;INITIALIZE POINTERS IN LOW MEMORY
MVI A,0C3H ;C3 IS A JMP INSTRUCTION
STA 0 ;FOR JMP TO WBOOT
LXI H,WBOTE ;WBOOT ENTRY POINT
SHLD 1 ;SET ADDRESS FIELD FOR JMP AT 0
;
STA 5 ;FOR JMP TO BDOS
LXI H,BDOS+6 ;BDOS ENTRY POINT
SHLD 6 ;ADDRESS FIELD OF JUMP AT 5 TO BDOS
;
LXI B,80H ;DEFAULT DMA ADDRESS IS 80H
CALL SETDMA
;
;PUT ACTIVE DISK NUMBER (STORED IN LOCATION 4) IN C
LDA 04H
MOV C,A
DI
ORG ccp ;GO TO CPM FOR FURTHUR PROCESSING
END


File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,9 @@
mac b:xios $$pp+s
era b:xios.hx0
ren b:xios.hx0=b:xios.hex
mac b:xios $$+rpzsz
pip b:xios.hex=b:xios.hx0,b:xios.hex
genmod b:xios.hex b:xios.spr
era b:*.hex
era b:*.hx0


View File

@@ -0,0 +1,10 @@
era b:*.hex
era b:*.hx0
mac b:xios $$pzsz
ren b:xios.hx0=b:xios.hex
mac b:xios $$+rpzsz
pip b:xios.hex=b:xios.hx0,b:xios.hex
genmod b:xios.hex b:xios.spr
era b:*.hex
era b:*.hx0