Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

251 lines
6.5 KiB
Plaintext
Raw Permalink 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 'Concurrent CP/M Loader Program'
;*******************************************************
;
; The Loader Program opens the file 'CCPM.SYS'
; using the LBDOS and LBIOS and then reads it into
; memory. The DS register is set to the start of
; the Concurrent CP/M DATA area, and a JMPF to the first
; byte of the Concurrent CP/M code is executed.
;
; The first 128 byte record of the CCPM.SYS file is
; a header with the following format:
;
; +----+----+----+----+----+----+----+----+----+
; |TYPE| LEN | ABS | MIN | MAX |
; +----+----+----+----+----+----+----+----+----+
;
; type 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 the CCPM.SYS File. This header record
; is constructed automatically by the system
; generation utility GENCCPM. See the variables
; declared at 'SEC1:' where the first sector of
; the CCPM.SYS will be read.
;
; The following commands are used to generate CPMLDR.SYS
; RASM86 LBIOS
; RASM86 LPROG
; LINK86 LBIOS3.SYS = LBIOS,LPROG [DATA[ORIGIN[0180]]]
; GENLDR [nnnn]
;
; The following commands are used to generate the
; boot tracks image BOOTTRKS
; SID86
; #RDSKBOOT.SYS ;strips header and
; #WBOOT,180,37F ;default base page
; PIP BOOTTRKS = BOOT[O],CPMLDR.SYS[O]
;
;*******************************************************
CR equ 13
LF equ 10
CTYPE equ byte ptr 00h
CLEN equ word ptr 01h
CLDSEG equ word ptr 03h
DTYPE equ byte ptr 09h
DLEN equ word ptr 0Ah
DLDSEG equ word ptr 0Ch
CODETYPE equ 1 ;code type CMD header
DATATYPE equ 2 ;data type CMD header
; bdos function numbers
DRV_SET equ 14
F_OPEN equ 15
F_READ equ 20
F_DMASET equ 26
F_USERNUM equ 32
F_MULTISEC equ 44
F_DMA equ 51
;*******************************************************
;
; LOADER starts here
;
;*******************************************************
CSEG
org 0000h
public ?start
extrn ?conout:near, ?pmsg:near
?start: ; loader entry from BDOS init
;------
mov si,offset signon ;print signon message
call ?pmsg
mov dl,0
mov cl,DRV_SET ! int 224 ;select boot drive
mov dl,0
mov cl,F_USERNUM ! int 224 ;set user number
mov dx,offset ccpm_fcb
mov cl,F_OPEN ! int 224 ;open CCPM.SYS file
cmp al,255 ! jne perr ;insure no error on open
mov si,offset nofile
error:
call ?pmsg ;print no SYSTEM file message
halt:
sti
hlt ;then halt the machine
jmps halt
perr:
mov dx,offset sec1
mov cl,F_DMASET ! int 224 ;set DMA offset address
mov dl,1 ;set Multi-sector count to 1
mov si,ds ;SI = DMA segment address
call read_rec ;read first record
mov bx,offset sec1
cmp CTYPE[bx],CODETYPE ;code type must = 1
je chk_data
badhdr:
mov si,offset hdrerr
jmp error
chk_data:
cmp DTYPE[bx],DATATYPE ;data type must = 2
jne badhdr
mov ax,CLDSEG[bx] ;code abs + code length
add ax,CLEN[bx] ;should be = to data abs
cmp ax,DLDSEG[bx] ! jne badhdr
add ax,DLEN[bx]
cmp ax,CLDSEG[bx] ;check for wrap around
jbe badhdr
mov ccpm_init,0000h ;set O.S. entry offset to 0000h
mov ax,CLDSEG[bx]
mov ccpm_init+2,ax ;set O.S. entry segment
hdrok:
mov si,offset csegmsg ;print out starting code and data
call ?pmsg ; on console
mov ax,word ptr sec1+CLDSEG
call phex ;print base code segment
mov si,offset dsegmsg
call ?pmsg ;print base data segment
mov ax,word ptr sec1+DLDSEG
call phex
mov dx,0
mov cl,F_DMASET ! int 224 ;set DMA offset to 0
;set multi_sector count to 127
mov dl,127 ;to align reads with physical sectors
mov si,word ptr sec1+CLDSEG ;initial DMA segment
call read_rec ;read next 127 sectors
jz done ;Z flag set -> EOF
add si,8*127 ;increment dma segment
mov dl,128 ;set multi-sector count to 128
call read_rec ;read next 128 sectors
jz done ;Z flag set -> EOF
readit1:
add si,8*128 ;increment dma segment
call read_data ;read next 128 sectors
jnz readit1 ;Z flag set -> EOF
done:
mov si,offset crlf ;print carriage return, line feed
call ?pmsg
mov ds,word ptr sec1+DLDSEG ;CCP/M data segment
jmpf cs:dword ptr ccpm_init ;leap to CCP/M initialization
;-------------------------------------------------------
; subroutines
;-------------------------------------------------------
read_rec:
;--------
; Entry: DL = multisector count
; SI = dma segment
mov cl,F_MULTISEC ! int 224 ;set multi-sector count to 128
read_data:
;---------
; Entry: SI = dma segment
; Exit: Z flag set if EOF
; Z flag reset if no error
mov dx,si
mov cl,F_DMA ! int 224 ;set DMA segment for disk IO
mov dx,offset ccpm_fcb
mov cl,F_READ ! int 224 ;next 128 sector read
cmp al,1! jnbe read_error
ret
read_error:
mov si,offset rerr ;print READ ERROR message
jmp error
phex: ;print 4 hex characters from ax
;----
; Entry: AX = hex value to print
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
;----
; Entry: AL = hex character to print
and al,0fh
cmp al,9 ! ja p10 ;above 9 ?
add al,'0' ;digit
jmps prn
p10:
add al,'A'-10 ;hex digit A-F
prn:
mov dl,al
putchar:
;-------
; Entry: DL = character to send to console
mov cl,dl
jmp ?conout
; code segment variable
ccpm_init rw 2 ;double word entry to Concurrent CP/M
;*******************************************************
;
; DATA AREA
;
;*******************************************************
DSEG
signon db 'Concurrent CP/M System Loader V1.0 (02/16/84)',0
nofile db CR,LF,'CCPM.SYS Not Found On Boot Disk',0
rerr db CR,LF,'Error Reading CCPM.SYS',0
hdrerr db CR,LF,'Bad Header Record in CCPM.SYS',0
csegmsg db CR,LF,'Code Paragraph Address = ',0
dsegmsg db CR,LF,'Data Paragraph Address = ',0
crlf db CR,LF,0
ccpm_fcb db 0,'CCPM ','SYS',0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0
;-------------------------------------------------------
sec1 rb 128 ;read first sector of CCPM.SYS
;here (header record)
;*******************************************************
END