;**************************************************************** ;* * ;* 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