mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
240 lines
5.5 KiB
Plaintext
240 lines
5.5 KiB
Plaintext
title 'CP/M-86 Loader'
|
||
|
||
; The CPMLDR consists of this module along with the
|
||
; LDRBDOS and LBIOS.
|
||
|
||
; CPMLDR resides on the first two tracks of a
|
||
; CP/M-86 system diskette and is brought into memory
|
||
; by the ROM bootstrap loader to load initiate CP/M-86
|
||
|
||
; It opens the file 'CPM.SYS' using the LDRBDOS and LBIOS
|
||
; and then reads it into memory. Finally, a jump to the BIOS
|
||
; initialization entry point starts CP/M-86
|
||
|
||
; The first 128 byte record of the CPM.SYS file is a header
|
||
; with the following format:
|
||
|
||
; ty rb 1 ;seg type (not used here)
|
||
; len rw 1 ;length (not used here)
|
||
; abs dw ldrstart ;absolute segment address for LOADER
|
||
; min rw 1 ;minimum mem (not used here)
|
||
; max rw 1 ;max mem needed (not used here)
|
||
|
||
; (This header record is constructed automatically by the
|
||
; GENCMD utility).
|
||
|
||
; CPMLDR 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.
|
||
|
||
false equ 0
|
||
true equ not false
|
||
|
||
cr equ 0dh
|
||
lf equ 0ah
|
||
|
||
lbios_offset equ 1200h ; offset of LBIOS
|
||
|
||
biosoff equ 2500h ; offset of BIOS from start of CPM.SYS
|
||
; this is the entry point into CPM.SYS
|
||
|
||
bootdrv equ 0 ; boot drive always zero
|
||
|
||
; 128 bytes of CPM.SYS
|
||
|
||
lbdosoff equ 406H ;location of LBDOS in LOADER
|
||
|
||
bdos_int equ 224 ;lbdos interrupt number
|
||
|
||
; dummy section for interrupt vectors
|
||
|
||
dseg 0
|
||
org 0
|
||
abs_zero rw 2*bdosint
|
||
bdos_offset rw 1
|
||
bdos_segment rw 1
|
||
|
||
; bdos function numbers
|
||
|
||
coutf equ 2
|
||
pstrf equ 9
|
||
seldsk equ 14
|
||
openf equ 15
|
||
readsf equ 20
|
||
dmaf equ 26
|
||
dmabf equ 51
|
||
|
||
|
||
;*******************************
|
||
;*
|
||
;* CPMLDR starts here
|
||
;*
|
||
;*******************************
|
||
|
||
cseg
|
||
org 0 ; JMPF to here from boot ROM
|
||
|
||
jmp LBIOS ; allow loader BIOS to
|
||
; initialize
|
||
start: ; loader BIOS jumps here
|
||
|
||
xor ax,ax ! mov ds,ax ; temp DS at absolute zero
|
||
mov bdos_offset,lbdosoff ; 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
|
||
|
||
call initlbdos ;warm up lbdos and lbios
|
||
call openfnc ;open CPM.SYS
|
||
cmp al,255 ! jne perr ; insure good file
|
||
mov dx,offset nofile ! call msg ; no CPM.SYS file
|
||
jmp stop ; then halt the machine
|
||
perr:
|
||
mov dx,cs ! call setdmab
|
||
mov dx,offset page1 ! call setdma ;read first page of CPM.SYS
|
||
call read
|
||
mov ax,word ptr page1+3 ;get abs field from header
|
||
mov ldseg,ax ; save it and
|
||
mov dx,ax ! call setdmab ; set DMA segment for disk IO
|
||
mov dx,offset segment ! call msg ; put memory map on console
|
||
mov ax,ldseg ! call phex ; print base system segment
|
||
|
||
;
|
||
mov dx,0 ;offset of CPM in segment
|
||
readit:
|
||
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 ; address for next record
|
||
jmp readit
|
||
done:
|
||
mov dx,offset lenmsg ! call msg ; print length message
|
||
pop ax ! dec ax ! call phex ; print last address
|
||
call pcrlf ; and a crlf
|
||
jmpf bios ; leap to BIOS 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: hlt ; hard stop 8086 for error
|
||
jmp stop
|
||
|
||
;********************************
|
||
;*
|
||
;* DATA AREA
|
||
;*
|
||
;********************************
|
||
|
||
nofile db cr,lf,'The File CPM.SYS Not Found On This Disk$'
|
||
rerr db cr,lf,'Error In Reading CPM.SYS$'
|
||
segment db cr,lf,'Segment Address = $'
|
||
lenmsg db cr,lf,' Last Offset = $'
|
||
crlf db cr,lf,'$'
|
||
|
||
|
||
; vector for jmpf indirect to start CP/M
|
||
|
||
bios dd abs_zero ; (dummy value)
|
||
|
||
org offset bios ; overlay preceding with DW's
|
||
|
||
biosstart dw biosoff ; first word is BIOS offset
|
||
ldseg rw 1 ; second is segment to put CPM.SYS
|
||
|
||
|
||
fcb db 0,'CPM ','SYS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||
|
||
org (offset $+1) and 0FFFEh ; even address for stack
|
||
rw 32
|
||
stack equ offset $
|
||
|
||
dseg
|
||
org stack
|
||
page1 rb 128
|
||
|
||
|
||
; dummy section for BIOS init label
|
||
org lbios_offset
|
||
lbios:
|
||
|
||
end
|
||
|