mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-27 10:24:19 +00:00
Upload
Digital Research
This commit is contained in:
321
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.A86
Normal file
321
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/04/LDMPM.A86
Normal file
@@ -0,0 +1,321 @@
|
||||
title 'MP /M-86 Loader'
|
||||
|
||||
; The MPMLDR consists of this module along with the
|
||||
; LDBDOS and LDBIOS. The LDBDOS is the same as for
|
||||
; for CP/M-86, and the LDBIOS has only the login message
|
||||
; changed.
|
||||
|
||||
; MPMLDR resides on the first two tracks of a
|
||||
; MP/M-86 system diskette and is brought into memory
|
||||
; by the ROM bootstrap loader to load initiate MP/M-86
|
||||
|
||||
; It opens the file 'MPM.SYS' using the LDBDOS and LDBIOS
|
||||
; and then reads it into memory. The DS register is set
|
||||
; to the start of the MPM DATA area, and a JMPF to the
|
||||
; first byte of the MPM code is executed.
|
||||
|
||||
; The first 128 byte record of the MPM.SYS file is a header
|
||||
; with the following format:
|
||||
|
||||
; ty rb 1 ;seg type
|
||||
; len rw 1 ;length
|
||||
; abs dw 1 ;absolute segment address for LOADER
|
||||
; min rw 1 ;minimum mem
|
||||
; max rw 1 ;max mem needed
|
||||
|
||||
; The code is expected first and then the data within MPM.SYS
|
||||
; This header record is constructed automatically by the
|
||||
; GENSYS-86 utility. See the variables declared at 'SEC1:'
|
||||
; where the first sector of MPM.SYS will be read
|
||||
|
||||
; MPMLDR may be read into any segment that does not
|
||||
; overlap the desired system load segment as it makes
|
||||
; all memory references using copies of the CS: register
|
||||
; it is entered with.
|
||||
;
|
||||
; For debugging under CP/M and DDT a 'IB' can be used to force a
|
||||
; break to DDT just before 'Far Jumping' to MPM.
|
||||
;
|
||||
false equ 0
|
||||
true equ not false
|
||||
|
||||
cr equ 0dh
|
||||
lf equ 0ah
|
||||
|
||||
ldbdos_offset equ 406H ;offset of LDBDOS
|
||||
mldbios_offset equ 1200h ;offset of LDBIOS
|
||||
bdos_int equ 224 ;lbdos interrupt number
|
||||
|
||||
bootdrv equ 0 ; boot drive always zero
|
||||
codetype equ 1 ; code type CMD header
|
||||
datatype equ 2 ; data type CMD header
|
||||
|
||||
; dummy section for interrupt vectors
|
||||
|
||||
dseg 0
|
||||
org 0
|
||||
abs_zero rw 2*bdosint
|
||||
bdos_offset rw 1
|
||||
bdos_segment rw 1
|
||||
|
||||
fcb1 equ 5dh ; look here for 'B' to break
|
||||
ddt_int equ 3 ; DDT interrupt
|
||||
|
||||
; bdos function numbers
|
||||
|
||||
coutf equ 2
|
||||
pstrf equ 9
|
||||
seldsk equ 14
|
||||
openf equ 15
|
||||
readsf equ 20
|
||||
dmaf equ 26
|
||||
dmabf equ 51
|
||||
|
||||
|
||||
;*******************************
|
||||
;*
|
||||
;* MPMLDR starts here
|
||||
;*
|
||||
;*******************************
|
||||
|
||||
cseg ; JMPF to here from boot ROM
|
||||
org 0
|
||||
jmp start ; if loaded under DDT this
|
||||
; gets overlayed and IP = 100H
|
||||
; want 100h byte header for
|
||||
; 'IB' option
|
||||
|
||||
db 'COPYRIGHT (C) 1981,' ; found by serial program
|
||||
db ' DIGITAL RESEARCH '
|
||||
db '654321'
|
||||
db ' MP/M-86 Loader V2.0 (9/21/81)'
|
||||
|
||||
org 80H ; read first sector of MPM.SYS
|
||||
sec1 rb 128 ; here
|
||||
|
||||
org offset sec1 ;CMD header fields
|
||||
ctype rb 1 ;type
|
||||
clen rw 1 ;length
|
||||
cldseg rw 1 ;abs
|
||||
cmin rw 1 ;minimum
|
||||
cmax rw 1 ;maximum
|
||||
dtype rb 1
|
||||
dlen rw 1
|
||||
dldseg rw 1
|
||||
dmin rw 1
|
||||
dmax rw 1
|
||||
|
||||
org 100H
|
||||
start: ; execution begins here if DDT
|
||||
jmp mldbios ; initialize mldbios
|
||||
; mldbios returns here: 103H
|
||||
xor ax,ax ! mov ds,ax ; temp DS at absolute zero
|
||||
mov bdos_offset,offset ldbdos_offset ; to patch in interrupt table
|
||||
mov bdos_segment,cs ; offset and segment
|
||||
mov ax,cs ! mov ss,ax ; make ss, ds, es = cs
|
||||
mov ds,ax ! mov es,ax
|
||||
mov sp,offset(stack) ; set up local stack
|
||||
|
||||
mov dx,offset signon
|
||||
call msg
|
||||
call initlbdos ; warm up lbdos and lbios
|
||||
call openfnc ; open MPM.SYS
|
||||
cmp al,255 ! jne perr ; insure good file
|
||||
mov dx,offset nofile ! call msg ; no MPM.SYS file
|
||||
jmp stop ; then halt the machine
|
||||
perr:
|
||||
mov dx,cs ! call setdmab
|
||||
mov dx,offset sec1 ! call setdma ; read first sector of MPM.SYS
|
||||
call read
|
||||
cmp ctype,codetype ; code should be first
|
||||
jnz badhdr
|
||||
cmp dtype,datatype ; then data
|
||||
jnz badhdr
|
||||
mov ax,cldseg ; code abs + code length
|
||||
add ax,clen ; should be = to data abs
|
||||
cmp ax,dldseg ! jnz badhdr
|
||||
add ax,dlen ! cmp ax,cldseg ; check for wrap around
|
||||
ja hdrok
|
||||
badhdr:
|
||||
mov dx,offset hdrerr ! call msg
|
||||
jmp stop
|
||||
hdrok:
|
||||
mov dx,offset csegment ! call msg ; put memory map on console
|
||||
mov ax,cldseg ! call phex ; print base code segment
|
||||
mov dx,offset dsegment ! call msg ; print base data segment
|
||||
mov ax,dldseg ! call phex
|
||||
;
|
||||
mov dx,cldseg
|
||||
mov dmab,dx ; initial DMA segment
|
||||
readit1:
|
||||
call setdmab ; set DMA segment for disk IO
|
||||
mov dx,0 ; offset of MPM in segment
|
||||
readit2:
|
||||
call setdma ; set DMA offset for
|
||||
push dx ! call read ; next sector read
|
||||
cmp al,01H ! je done ; check for EOF
|
||||
cmp al,0 ! je prerr ; check for good write
|
||||
mov dx,offset rerr ! call msg ; print READ ERROR message
|
||||
jmp stop ; hard stop on any error
|
||||
|
||||
prerr: pop dx ! add dx,80H
|
||||
cmp dx,0 ; more than 64K ?
|
||||
jnz readit2
|
||||
add dmab,1000h ; add 64K to base
|
||||
mov dx,dmab
|
||||
jmp readit1
|
||||
done:
|
||||
pop ax ; number of bytes read
|
||||
mov cl,4
|
||||
shr ax,cl ; number of paragraphs read
|
||||
add ax,dmab ; number of 64K segments read
|
||||
sub ax,cldseg ; (dmab - cldseg)
|
||||
mov cx,clen
|
||||
add cx,dlen
|
||||
cmp ax,cx
|
||||
jae lenok ; MPM.SYS at least as long
|
||||
mov dx,offset shortmsg ; as header claims ?
|
||||
call msg ! jmp stop
|
||||
lenok:
|
||||
push cx ; clen + dlen in cx
|
||||
mov dx,offset lenmsg ! call msg ; print length message
|
||||
pop ax
|
||||
add ax,cldseg
|
||||
dec ax ; last paragraph
|
||||
call phex
|
||||
call pcrlf ; and a crlf
|
||||
|
||||
mov ax,cldseg
|
||||
mov mpmcseg,ax
|
||||
mov ds,dldseg ; MP/M data segment
|
||||
|
||||
mov al, cs:.fcb1 ; must use CS over-ride
|
||||
cmp al,'B'
|
||||
jnz gompm
|
||||
int ddt_int ; break to mpm
|
||||
gompm:
|
||||
jmpf mpm ; leap to MPM initialization
|
||||
|
||||
;*****************************
|
||||
;*
|
||||
;* subroutines
|
||||
;*
|
||||
;*****************************
|
||||
|
||||
;******
|
||||
phex: ;print 4 hex characters from ax
|
||||
mov cx,0404h ; 4 in both CH and CL
|
||||
lhex:
|
||||
rol ax,cl ; rotate left 4
|
||||
push cx ! push ax ; save crucial registers
|
||||
call pnib ; print hex nibble
|
||||
pop ax ! pop cx ; restore registers
|
||||
dec ch ! jnz lhex ; and loop four times
|
||||
ret
|
||||
pnib: ;print low nibble in AL as hex char
|
||||
and al,0fh ! cmp al,9
|
||||
ja p10 ;above 9 ?
|
||||
add al,'0' ;digit
|
||||
jmp prn
|
||||
p10: add al,'A'-10 ;char a-e
|
||||
prn: mov dl,al
|
||||
|
||||
;******
|
||||
putchar:
|
||||
mov cl,coutf
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
initlbdos:
|
||||
mov cl,seldsk ! mov dx,bootdrv ; select boot disk
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
openfnc:
|
||||
mov cl,openf ! mov dx,offset fcb ; fcb already initialized
|
||||
mov cl,openf
|
||||
jmp sys_vec
|
||||
|
||||
;********
|
||||
;
|
||||
setdma: ;set new dma addr in dx
|
||||
mov cl,dmaf
|
||||
jmp sys_vec
|
||||
|
||||
;********
|
||||
;
|
||||
setdmab: ; set new dma segment base from DX
|
||||
mov cl,dmabf
|
||||
jmp sys_vec
|
||||
|
||||
;******
|
||||
;
|
||||
pcrlf: mov dx,offset crlf ;print carriage return, line feed
|
||||
|
||||
;******
|
||||
;
|
||||
msg: ;print msg starting at dx until $
|
||||
mov cl,pstrf ;print string function
|
||||
jmp sys_vec
|
||||
|
||||
;*****
|
||||
;
|
||||
read:
|
||||
mov dx,offset fcb ! mov cl,readsf
|
||||
; jmp sys_vec
|
||||
|
||||
;******
|
||||
;
|
||||
sys_vec:
|
||||
int bdos_int
|
||||
ret
|
||||
|
||||
;******
|
||||
;
|
||||
stop: mov ax,0 ; hard stop 8086 for error
|
||||
mov ds,ax
|
||||
mov word ptr .8h,ax
|
||||
mov word ptr .0ah,cs
|
||||
stop2:
|
||||
jmp stop2
|
||||
|
||||
;********************************
|
||||
;*
|
||||
;* DATA AREA
|
||||
;*
|
||||
;********************************
|
||||
|
||||
signon db cr,lf,lf,'MP/M-86 V2.0 Loader',cr,lf,'$'
|
||||
nofile db cr,lf,'The File MPM.SYS Not Found On This Disk$'
|
||||
rerr db cr,lf,'Error In Reading MPM.SYS$'
|
||||
hdrerr db cr,lf,'Bad Header Record in MPM.SYS$'
|
||||
shortmsg db cr,lf,'MPM.SYS Too Short $'
|
||||
csegment db cr,lf,'Code Paragraph Address = $'
|
||||
dsegment db cr,lf,'Data Paragraph Address = $'
|
||||
lenmsg db cr,lf,'Last Paragragh = $'
|
||||
crlf db cr,lf,'$'
|
||||
|
||||
|
||||
; vector for jmpf indirect to start MP/M
|
||||
|
||||
mpm dd abs_zero ; (dummy value)
|
||||
org offset mpm ; overlay preceding with DW's
|
||||
mpmstart dw 0 ; first word of MPM code
|
||||
mpmcseg rw 1 ; second is segmet of MPM code
|
||||
|
||||
dmab rw 1 ; current DMA segment
|
||||
fcb db 0,'MPM ','SYS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
; look on m disk first
|
||||
|
||||
org (offset $+1) and 0FFFEh ; even address for stack
|
||||
rw 32
|
||||
stack equ offset $
|
||||
db 0
|
||||
|
||||
; dummy section for BIOS init label
|
||||
|
||||
org mldbios_offset
|
||||
mldbios:
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user