Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 8000 (CPM8K)/P-CP M-Z8K SOURCES/bdos/bdosif.z8k
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

250 lines
5.0 KiB
Plaintext

;****************************************************************
;* *
;* CP/M-Z8K Basic Disk Operating System interface module *
;* For "C" version of CP/M-Z8K *
;* *
;* Copyright (c) 1982 Digital Research, Inc. *
;* *
;* Version 0.2 -- September 22, 1982 *
;* Z8000 version -- 821014 *
;* *
;****************************************************************
__text: .sect
;****************************************************
;*
;* Globals
;*
;****************************************************
.global _bios1 ; 6 BIOS entry points from BDOS
.global _bios2
.global _bios3
.global _bios4
.global _bios5
.global _bios6
.global _traphnd ; trap #2 handler
.global _swap ; byte swapper
.global _udiv ; unsigned divide routine
;****************************************************
;*
;* Externals and Constants
;*
;****************************************************
.global __bdos ; BDOS entry point in bdosmain
;* The following were put in so that all BDOS modules were
;* referenced, so they could be put in a library
.global _constat ; references conbdos.o
.global _dirscan ; references dskutil.o
.global _create ; references fileio.o
.global _bdosrw ; references bdosrw.o
biosf .equ 50
setsupf .equ 62
;****************************************************
;*
;* Trap Handler
;*
;* rcode = bdos(command, (long)parameter)
;*
;* rr6: parameter
;* r5: command
;* returns
;* r7: result
;*
;* called SEGMENTED with caller's registers
;* saved on stack, and all but rr0 intact in
;* registers.
;*
;* Calls __bdos(cmd, (word)param, (addr)param)
;*
;****************************************************
_traphnd:
ldctl r0,FCW ;go non-segmented
res r0,#15
ldctl FCW,r0
;
; check for functions handled by assembly
; language routines
;
cp r5,#setsupf ; set system mode
jr eq setsup
cp r5,#biosf ; call bios direct
jr eq bioscall
;
; If caller was non-segmented user program,
; get segment number from his program counter
;
ldl rr2,rr6
ld r0,34+4(r15) ;caller's fcw
bit r0,#15
jr nz callC ; segmented
bit r0,#14
jr nz callC ; system
ld r2,36+4(r15) ; user nonseg.
; set seg from PC
;
; Call C main routine
;
callC:
pushl @r15,rr2 ; xaddr param.
push @r15,r7 ; word param
push @r15,r5 ; command
call __bdos
add r15,#8
;
; Return result in caller's r7.
; Restore segmented mode and return
;
ld 14+4(r15),r7
ldctl r0,FCW ;go segmented
set r0,#15
ldctl FCW,r0
ret
;
; direct BIOS call function
;
bioscall:
;
; If caller was non-segmented user program,
; get segment number from his program counter
;
ld r0,34+4(r15) ;caller's fcw
bit r0,#15
jr nz callBios ; segmented
bit r0,#14
jr nz callBios ; system
ld r6,36+4(r15) ; user nonseg.
ld r2,r6 ; set seg from PC
; save in r2, also
ldctl r0,FCW ;go segmented
set r0,#15
ldctl FCW,r0
ldm r3,@r6,#5 ;get parameters
ld r4,r2 ;set segments
ld r6,r2
sc #3 ;call BIOS
ret ;done
callBios:
ldctl r0,FCW ;go segmented
set r0,#15
ldctl FCW,r0
ldm r3,@r6,#5 ;get parameters
sc #3 ;call BIOS
ret ;done
;
; Set supervisor mode procedure -- VERY DANGEROUS
;
; Status is set to SYSTEM, SEGMENTED.
; Interrupt status will be that at the time
; of the call.
;
setsup:
ld r0,34+4(r15)
set r0,#14 ;set system
set r0,#15 ; and segmented
ld 34+4(r15),r0 ; in user FCW
ldctl r0,FCW ;go segmented
set r0,#15
ldctl FCW,r0
ret ;return
;****************************************************
;*
;* BIOS Interface Routines
;*
;* Note - there are 6 BIOS entry points from the BDOS,
;* labelled BIOS1 - BIOS6, depending on the
;* parameters passed.
;*
;****************************************************
_bios5:
; For BIOS functions sectran and set exception vector
; (funct, word, long) offsets 2, 4, 6
ldl rr6,6(r15) ; get 2nd param (long)
jp _bios2 ; join common routine
_bios4:
; For BIOS function seldsk
; (func, word, word) offsets 2, 4, 6
ld r7,6(r15) ; get 2nd param (word)
clr r6 ; extend to ulong
jp _bios2 ; join common routine
_bios3:
; For BIOS function set dma
; (func, long) offsets 2, 4
ldl rr4,4(r15) ; get 1st param (long)
subl rr6,rr6 ; clear second
jp _bios1 ; join common routine
_bios2:
; For all BIOS functions with a word parameter
; (func, word) offsets 2, 4
ld r5,4(r15) ; get 1st param (word)
clr r4 ; extend to ulong
_bios6:
_bios1:
; For all BIOS functions that have no parameter
; other than function number
ld r3,2(r15) ; get function number
sc #3 ; do BIOS call
ret ; returns value in rr7
;****************************************************
;*
;* Utility Subroutines
;*
;* swap(word) swap bytes of a word
;*
;* uword udiv((long) dividend,
;* (uword) divisor,
;* (uword *)rem )
;*
;****************************************************
_swap:
ld r7,2(r15)
exb rh7,rl7
ret
_udiv:
ldl rr2,2(r15) ;long dividend
subl rr0,rr0 ; as unsigned quad
ld r5,6(r15) ;word divisor
clr r4 ; as unsigned long
ldl rr6,8(r15) ;->result
divl rq0,rr4
ld @r7,r1 ; store remainder
ld r7,r3 ; return quotient
clr r6
ret