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,237 @@
;---------------------------------------------------------------------
; LOADCPM.ASM (FOR CAL-PC MSDOS 2.11 - ASSEMBLE USING A86.COM)
; 28-10-88
; STEPHEN HUNT
;---------------------------------------------------------------------
; 28-12-89
; Modified to attempt to open the CPM.SYS file in the root directory
; if it could not be found in the current directory
;---------------------------------------------------------------------
;
cr equ 0dh ; carriage return
lf equ 0ah ; line feed
eof equ 01ah ; end of file marker
;
dos equ 21h
;
;---------------------------------------------------------------------
; jump to start of code
;---------------------------------------------------------------------
;
loadcpm:
;
jmp start
;
db 'LOADCPM version 1.1 Copyright (C) Stephen Hunt'
db eof
;
;---------------------------------------------------------------------
; tell 'em what were up to
;---------------------------------------------------------------------
;
start:
;
mov dx,offset loading
call print_string
;
;---------------------------------------------------------------------
; open the CPM.SYS file
;---------------------------------------------------------------------
;
mov dx,offset cpm_sys+1 ; assume 'CPM.SYS'
call open_cpm ; open file
jnc read_cpm_sys ; ok - continue
;
mov dx,offset cpm_sys ; assume '\CPM.SYS'
call open_cpm ; open file
jnc read_cpm_sys ; ok - continue
;
mov dx,offset err_open ; 'cannot find CPM.SYS'
jmp error_exit ; exit with error
;---------------------------------------------------------------------
; read the CPM.SYS file (upto 32k bytes, usually only 16k bytes)
;---------------------------------------------------------------------
;
read_cpm_sys:
;
mov bx,word ptr cpm_hnd
mov dx,offset cpm_buf
mov cx,32768
mov ah,03fh
int dos ; read 32768 bytes of CPM.SYS
;
mov word ptr cpm_siz,ax ; store number of bytes read
;
pushf ; save read error status
call closecpm ; close CPM.SYS file
popf ; restore read error status
;
jnc check_header ; continue if read successful
;
mov dx,offset err_read ; 'error reading CPM.SYS'
jmp error_exit ; exit with error
;---------------------------------------------------------------------
; check that the CPM.SYS header record is valid
;---------------------------------------------------------------------
;
check_header:
;
cmp word ptr cpm_siz,0 ; q. was anything read ?
jz check_header_err ; no - error
;
mov si,offset cpm_buf
cmp byte ptr 0[si],1 ; q. code segment group type present ?
jnz check_header_err ; no - error
;
mov ax,word ptr 1[si] ; get group length in paragraphs
mov dx,010h
mul dx ; convert to length in bytes
mov word ptr cpm_len,ax ; and store it
;
mov bx,word ptr cpm_siz
cmp bx,ax ; q. file size greater than code length ?
jb check_header_err ; no - error
;
sub bx,080h ; subtract length of header record
sub bx,ax ; then the code length
cmp bx,080h ; q. (file size less header) more than
; ; 128 bytes larger than code length ?
jae check_header_err ; yes - error
;
cmp word ptr 3[si],0 ; q. base segment defined ?
jz check_header_err ; no - error
;
mov ax,word ptr 1[si]
cmp ax,word ptr 5[si] ; q. code length equal minimum length ?
jnz check_header_err ; no - error
;
cmp word ptr 7[si],0 ; q. maximum length defined ?
jnz check_header_err ; yes - error
;
add si,9 ; point to next group descriptor
mov cx,128 -9
cld
;
check_header_loop:
;
cmp byte ptr 0[si],0 ; q. any more descriptors defined ?
jnz check_header_err ; yes - error
loop check_header_loop ; loop until finished
;
jmp reset_int3 ; reset int 3 vector
;
check_header_err:
;
mov dx,offset err_head ; 'invalid CPM.SYS header'
jmp error_exit ; exit with error
;---------------------------------------------------------------------
; reset interrupt 3 to use the prom interrupt 3 routine (FC00:32BE).
;---------------------------------------------------------------------
;
reset_int3:
;
push ds
mov dx,0fc00h ; segment FC00h
mov ds,dx
mov dx,032beh ; offset 32BEh
mov al,3
mov ah,025h
int dos ; reset int 3
pop ds
;---------------------------------------------------------------------
; relocate cpm image, set segment registers and jump to it.
;---------------------------------------------------------------------
;
move_cpm:
;
mov ax,word ptr cpm_buf +3
mov es,ax ; es points to cpm segment
;
mov si,offset cpm_buf +080h
xor di,di ; set source + destination pointers
;
mov cx,word ptr cpm_len ; set length of code to move
;
cld ; clear the direction flag
cli ; plus the interrupt flag
;
rep movsb ; move it !!!!
;
mov ds,ax
push ax ; push cpm segment address on stack
mov ax,02500h
push ax ; push bios cold boot address on stack
;
retf ; return far to CPM-86 !!!
;---------------------------------------------------------------------
; Subroutines
;---------------------------------------------------------------------
; Open CPM.SYS file
;---------------------------------------------------------------------
;
open_cpm:
;
xor al,al
mov ah,03dh
int dos ; open CPM.SYS file
mov word ptr cpm_hnd,ax ; save file handle
;
ret
;---------------------------------------------------------------------
; Close CPM.SYS file
;---------------------------------------------------------------------
;
close_cpm:
;
mov bx,word ptr cpm_hnd
mov ah,03eh
int dos ; close CPM.SYS file
;
ret
;---------------------------------------------------------------------
; print string at offset dx
;---------------------------------------------------------------------
;
print_string:
;
mov ah,09h
int dos ; print string
;
ret
;---------------------------------------------------------------------
; print string and exit
;---------------------------------------------------------------------
;
error_exit:
;
call print_string
mov ah,04ch
xor al,al
int dos ; return to dos
;
;---------------------------------------------------------------------
; data
;---------------------------------------------------------------------
;
loading db cr,lf,'Loading CP/M-86 $'
;
err_open db cr,lf,lf,'Unable to open CPM.SYS',cr,lf,'$'
err_read db cr,lf,lf,'Error reading CPM.SYS',cr,lf,'$'
err_head db cr,lf,lf,'Invalid CPM.SYS header',cr,lf,'$'
;
cpm_sys db '\CPM.SYS',0 ; asciiz file name
cpm_hnd dw 0 ; file handle
cpm_siz dw 0 ; file size
cpm_len dw 0 ; code length
;
cpm_buf db 32768 dup (0) ; cpm.sys load buffer
;
db 0 ; spare
;
;---------------------------------------------------------------------
;
;---------------------------------------------------------------------
;
end