Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 8000 (CPM8K)/CPM 8K 1.1/disk4/biosmem.8kn
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1 line
4.0 KiB
Plaintext

;******* biosmem.8kn for cpm.sys + cpmldr.sys ********
;* Copyright 1984, Digital Research Inc.
;*
;* Memory Management for CP/M-8000(tm) BIOS
;* for Olivetti M20 (Z8001) system.
;*
;* 821013 S. Savitzky (Zilog) -- split modules
;* 820913 S. Savitzky (Zilog) -- created.
;* 840815 R. Weiser (DRI) -- conditional assembly
;*
__text: .sect
;****************************************************
;*
;* This module copies data from one memory space
;* to another. The machine-dependent parts of
;* the mapping are well isolated.
;*
;* Segmented operations are well-isolated, and
;* are either the same as their non-segmented
;* counterparts, or constructed using macros.
;*
;****************************************************
;****************************************************
;*
;* Global declarations
;*
;****************************************************
.global _sysseg, _usrseg, _sysstk, _psap
.global memsc
;****************************************************
;*
;* Externals
;*
;****************************************************
.global xfersc
;****************************************************
;*
;* System/User Memory Access
;*
;* _mem_cpy( source, dest, length)
;* long source, dest, length;
;* _map_adr( addr, space) -> paddr
;* long addr; int space;
;*
;* _map_adr( addr, -1) -> addr
;* sets user seg# from addr
;*
;* _map_adr( addr, -2)
;* control transfer to context at addr.
;*
;* system call: mem_cpy
;* rr6: source
;* rr4: dest
;* rr2: length (0 < length <= 64K)
;* returns
;* registers unchanged
;*
;* system call: map_adr
;* rr6: logical addr
;* r5: space code
;* r4: ignored
;* rr2: 0
;* returns
;* rr6: physical addr
;*
;* space codes:
;* 0: caller data
;* 1: caller program
;* 2: system data
;* 3: system program
;* 4: TPA data
;* 5: TPA program
;*
;* x+256 x=1, 3, 5 : segmented I-space addr.
;* instead of data access
;*
;* FFFF: set user segment
;*
;****************************************************
memsc: ;memory manager system call
; CALLED FROM SC
; IN SEGMENTED MODE
; rr6: source
; rr4: dest / space
; rr2: length / 0
testl rr2
jr z mem_map
mem_copy: ; copy data.
; rr6: source
; rr4: dest
; rr2: length
ldirb @r4,@r6,r3
ldl rr6,rr4 ; rr6 = dest + length
ret
mem_map: ; map address
; rr6: source
; r4: caller's seg.
; r5: space
; r2: caller's FCW
NONSEG
cp r5,#-2 ; space=-2: xfer
jp eq xfersc
ld r4,scseg+4(r15)
ld r2,scfcw+4(r15)
calr map_1
ldl cr6+4(r15),rr6 ; return rr6
SEG
ret
map_1: ; dispatch
cp r5,#0FFFFh
jr eq set_usr ; space=-1: user seg
cpb rl5,#0
jr eq call_data
cpb rl5,#1
jr eq call_prog
cpb rl5,#2
jr eq sys_data
cpb rl5,#3
jr eq sys_prog
cpb rl5,#4
jr eq usr_data
cpb rl5,#5
jr eq usr_prog
ret ;default: no mapping
set_usr: ;-1: set user seg.
ld _usrseg,r6
ret
;*
;*** THE FOLLOWING CODE IS SYSTEM-DEPENDENT ***
;*
;* rr6= logical address
;* r4 = caller's PC segment
;* r2 = caller's FCW
;* returns
;* rr6= mapped address
;*
;* Most of the system dependencies are in map_prog,
;* which maps a program segment into a data segment
;* for access as data.
;*
call_data:
bit r2,#15 ; segmented caller?
ret nz ; yes-- use passed seg
ld r6,r4 ; no -- use pc segment
ret ; already mapped
call_prog:
bit r2,#15 ; segmented caller?
jr nz map_prog ; yes-- use passed seg
ld r6,r4 ; no -- use pc segment
jr map_prog ; map prog as data
sys_data:
ld r6, _sysseg
ret
sys_prog:
ld r6, _sysseg
ret ; assume sys does not
; separate code, data
usr_data:
ld r0, #-1
cp r0, _usrseg
ret eq
ld r6, _usrseg
ret
usr_prog:
ld r0, #-1
cp r0, _usrseg
jr eq map_prog
ld r6, _usrseg
jr map_prog
map_prog: ;map program addr into data
; rr6 = address
testb rh5 ; data access?
ret nz ; no: done
and r6,#7F00h ; extract seg bits
; olivetti: segment 8 is the only one with
; separate I and D spaces, and
; the program space is accessed
; as segment 10's data.
cpb rh6,#8
ret ne
ldb rh6,#10
ret
cpb rh6,#8
ret ne
ldb rh6,#10
ret