home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG025.ARK
/
BOOT.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
6KB
|
338 lines
;STOIC DISK BOOTSTRAP
;J. SACHS 2/4/77
;
;***************************************************************************
;** COPYRIGHT (C) MASSACHUSETTS INSTITUTE OF TECHNOLOGY AND HARVARD **
;** UNIVERSITY, BIOMEDICAL ENGINEERING CENTER 1977. ALL RIGHTS RESERVED. **
;***************************************************************************
;DEFINE PARAMETERS
BSIZE EQU 200H ;BLOCK SIZE (BYTES)
RAM EQU 2000H ;START OF RAM
OFFSET EQU 0 ;LOAD OFFSET FOR DEBUGGING BOOTSTRAP
MAXRT EQU 8 ;MAXIMUM # OF RETRIES ON DISK
;DEFINE TEMPORARY VARIABLES
DBUF EQU RAM ;DIRECTORY BUFFER
FBUF EQU DBUF+BSIZE ;FILENAME BUFFER
DIRP EQU FBUF+7 ;DIRECTORY POINTER
FBLK EQU DIRP+2 ;FIRST BLOCK OF FILE
NBLKS EQU FBLK+2 ;# OF BLOCK IN FILE
;DEFINE PERIPHERAL ADDRESSES
TTYISR EQU 0E001H ;TTY INPUT STATUS REGISTER
TTYOSR EQU 0E002H ;TTY OUTPUT STATUS REGISTER
TTYIDR EQU 0E003H ;TTY INPUT DATA REGISTER
TTYODR EQU 0E004H ;TTY OUTPUT DATA REGISTER
DSKCR EQU 0DE00H ;DISK CONTROL REGISTER
DSKST EQU 0DE01H ;DISK STATUS REGISTER
DSKBL EQU 0DE02H ;DISK BLOCK #
DSKAD EQU 0DE04H ;DISK BUFFER ADDR
;BOOT FILE FORMAT
;
;1ST BLOCK
;
; WORD CONTENTS
;
; 0 LOAD ADDRESS
; 1 STARTING ADDRESS
; 2-256 UNUSED
;
;SUBSEQUENT BLOCKS CONTAIN A CORE IMAGE STARTING
;AT THE LOAD ADDRESS
;THE LENGTH OF THE FILE IS DETERMINED BY THE DIRECTORY
;DEFINE RESTART HANDLERS
ORG OFFSET
DI
STA 0DF00H ;CLEAR POWER LOW INTERRUPT FLAG
JMP BOOT
ORG OFFSET+(1*8)
DI
JMP RAM+3H
ORG OFFSET+(2*8)
DI
JMP RAM+6H
ORG OFFSET+(3*8)
DI
JMP RAM+9H
ORG OFFSET+(4*8)
DI
JMP RAM+0CH
ORG OFFSET+(5*8)
DI
JMP RAM+0FH
ORG OFFSET+(6*8)
DI
JMP 1400H ;FOR DEBUGGER
ORG OFFSET+(7*8)
DI
JMP RAM+15H
DERR: LXI H,DERM ;GIVE "DISK ERROR" MESSAGE
ERROR: CALL MSG
BOOT:
SIZE: LXI H,0C000H ;FIRST DEVICE ADDRESS
MVI A,55H ;ALTERNATING 1'S AND 0'S
SIZE1: DCX H ;DECREMENT TO NEXT LOC
MOV M,A ;STORE BYTE IN MEMORY
CMP M ;CAN READ IT BACK ?
JNZ SIZE1 ;NO, CONTINUE
SPHL ;YES, SET STACK PTR TO TOP OF MEMORY
LDA 0DF00H ;CHECK FOR POWER LOW
ANI 8
JNZ LOW ;YES, GIVE ERROR
GETN: LXI H,PROMPT ;TYPE "FILENAME ? "
CALL MSG
LXI H,FBUF ;INITIALIZE GET POINTER
MVI C,6 ;INITIALIZE GET COUNT
GETN1: CALL TTYIN ;GET CHAR FROM KEYBOARD
CALL TTYOU ;ECHO IT
CPI 177Q ;RUBOUT
JZ BOOT
CPI 15Q ;CR
JZ GETN2
MOV M,A ;STORE CHAR IN FILENAME BUFFER
INX H
DCR C ;6 CHARS YET ?
JNZ GETN1 ;NO
MVI A,15Q ;YES, OUTPUT AT CR
CALL TTYOU
GETN2: MVI A,12Q ;OUTPUT A LF
CALL TTYOU
MOV A,C ;ONLY CR TYPED ?
CPI 6
JZ RAM ;YES, JMP TO 1ST RAM LOCATION
MVI M,0 ;NO, STORE NULL AT END OF NAME
SEARCH: LXI H,0 ;READ IN DIRECTORY
LXI D,DBUF
LXI B,1
CALL DSKIN
JNZ DERR ;ERROR
LXI H,DBUF ;START OF DIRECTORY
SRCH1: SHLD DIRP ;SET DIRECTORY POINTER
MOV A,M ;END OF DIRECTORY ?
INX H
ORA M
JZ BOOT ;YES, ASK FOR ANOTHER NAME
MATCH: MVI C,6 ;MATCH 6 CHARS MAX
LHLD DIRP ;POINTER TO DIRECTORY ENTRY
LXI D,FBUF ;POINTER TO FILENAME BUFFER
MTCH1: LDAX D ;COMPARE NEXT CHAR OF NAMES
CMP M
INX D
INX H
JNZ SRCH2 ;MISMATCH, TRY NEXT DIRECTORY ENTRY
ORA A
JZ FOUND ;NULL, FOUND A MATCH
DCR C ;DONE ?
JZ FOUND ;YES, FOUND A MATCH
JMP MTCH1 ;KEEP CHECKING
SRCH2: LHLD DIRP ;INCREMENT DIRECTORY POINTER TO NEXT ENTRY
LXI D,8
DAD D
SHLD DIRP
JMP SRCH1 ;CHECK NEXT ENTRY
FOUND: LHLD DIRP ;POINTER TO DIRECTORY ENTRY
LXI D,6 ;GET FIRST BLOCK #
DAD D
MOV E,M
INX H
MOV D,M
XCHG
SHLD FBLK ;SAVE IT
LHLD DIRP ;POINTER TO DIRECTORY ENTRY
LXI D,14 ;GET LAST BLOCK #
DAD D
MOV E,M
INX H
MOV D,M
LHLD FBLK ;SUBTRACT FIRST BLOCK #
MOV A,H
CMA
MOV H,A
MOV A,L
CMA
MOV L,A
DAD D
SHLD NBLKS ;SAVE RESULT
LHLD FBLK ;READ 1ST BLOCK OF FILE
LXI D,DBUF
LXI B,1
CALL DSKIN
JNZ DERR ;ERROR
LHLD NBLKS ;GET LENGTH OF FILE
MOV C,L ;MOVE IT INTO BC
MOV B,H
LHLD DBUF+2 ;PUSH START ADDR ON STACK
PUSH H
LHLD DBUF ;LOAD ADDR IN DE
XCHG
LHLD FBLK ;FIRST BLOCK # IN HL
INX H
CALL DSKIN ;READ PROGRAM
JNZ DERR ;ERROR
RET ;START PROGRAM
LOW: LXI H,LOWM
JMP ERROR
PROMPT: DB 15Q,12Q,'FILENAME ? ',0
DERM: DB 15Q,12Q,'DISK ERROR',0
LOWM: DB 15Q,12Q,'POWER LOW',0
DSKIN: MOV A,H ;GET UNIT #
RAR
ANI 0FH
STA DSKCR ;SELECT UNIT
DSKI1: MOV A,B ;DONE ?
ORA C
RZ ;YES, RETURN WITH A = 0
MVI A,MAXRT ;SET RETRY COUNTER
DSKI3: PUSH PSW
SHLD DSKBL ;SET BLOCK #
XCHG
SHLD DSKAD ;SET BUFFER ADDR
XCHG
MOV A,H ;GET UNIT #
RAR
ANI 0FH
ADI 20H ;READ
STA DSKCR ;START TRANSFER
DSKI2: LDA DSKST ;GET STATUS
ANI 80H ;DONE ?
JZ DSKI2 ;NO
LDA DSKST ;GET STATUS
ANI 1 ;ERROR ?
JZ DSKI4 ;NO
POP PSW ;YES, GET RETRY COUNTER
DCR A
JNZ DSKI3 ;TRY AGAIN
INR A ;RETURN WITH A = 1
RET
DSKI4: POP PSW ;FLUSH RETRY COUNTER
INX H ;INCREMENT BLOCK #
PUSH H ;INCREMENT BUFFER ADDR BY BLOCK SIZE
LXI H,BSIZE
DAD D
XCHG
POP H
DCX B ;DECREMENT BLOCK COUNT
JMP DSKI1 ;READ SOME MORE
DSKOU: MOV A,H ;GET UNIT #
RAR
ANI 0FH
STA DSKCR ;SELECT UNIT
LDA DSKST ;GET STATUS
ANI 4
RNZ ;WRITE PROTECTED, RETURN WITH A = 4
DSKO1: MOV A,B ;DONE ?
ORA C
RZ ;YES, RETURN WITH A = 0
MVI A,MAXRT ;SET RETRY COUNTER
DSKO3: PUSH PSW
SHLD DSKBL ;SET BLOCK #
XCHG
SHLD DSKAD ;SET BUFFER ADDR
XCHG
MOV A,H ;GET UNIT #
RAR
ANI 0FH
ADI 40H ;WRITE
STA DSKCR ;START TRANSFER
DSKO2: LDA DSKST ;GET STATUS
ANI 80H ;DONE ?
JZ DSKO2 ;NO
LDA DSKST ;GET STATUS
ANI 1 ;ERROR ?
JZ DSKO4 ;NO
POP PSW ;YES, GET RETRY COUNTER
DCR A
JNZ DSKO3 ;TRY AGAIN
INR A ;RETURN WITH A = 1
RET
DSKO4: POP PSW ;FLUSH RETRY COUNTER
INX H ;INCREMENT BLOCK #
PUSH H ;INCREMENT BUFFER ADDR BY BLOCK SIZE
LXI H,BSIZE
DAD D
XCHG
POP H
DCX B ;DECREMENT BLOCK COUNT
JMP DSKO1 ;READ SOME MORE
;GET CHAR FROM TTY
TTYIN: LDA TTYISR
ORA A
JP TTYIN
LDA TTYIDR
ANI 177Q
RET
;TYPE A CHARACTER ON TTY
TTYOU: PUSH PSW
TTYO1: LDA TTYOSR
ORA A
JP TTYO1
POP PSW
STA TTYODR
RET
;TYPE A MESSAGE ON TTY
MSG: MOV A,M
INX H
ORA A
RZ
CALL TTYOU
JMP MSG
;ENTRY POINTS FOR KERNEL
ORG OFFSET+512-12
JMP TTYIN ;TTYIN
JMP TTYOU ;TTYOU
JMP DSKIN ;DSKIN
JMP DSKOU ;DSKOU
END
***EOF***