home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
KAYPRO
/
KP10BIOS.MQC
/
KP10BIOS.MAC
Wrap
Text File
|
2000-06-30
|
18KB
|
714 lines
title KAYPRO CBIOS for CP/M 2.2
;###############################################################
;## KAYPRO 10 CBIOS for CP/M 2.2 ##
;## Copyright (C) 1982 By Non-Linear Systems, Inc. ##
;## No warranty is made, expressed or implied. ##
;###############################################################
;## Last Update: 10/20/83 [01] ##
;###############################################################
;
;History:
; Add secondary xlate table and build in ability to have
; function keys.
; Steven R. Fabian
; Initialization of modem port on a cold boot.
; Steven R. Fabian
; Add Parallel port driver using a time delay.
; Steven R. Fabian
;
true equ 0ffh
false equ 0
;
;****************************************************************
;* *
;* This BIOS can support versions D, F and G versions of the *
;* Kaypro 10 CP/M system, if the proper equates are set. Set *
;* one and only one of the following three equates to true; *
;* be sure the other two are false. *
;* *
versd equ false ; for version 2.2D *
versf equ false ; for version 2.2F *
versg equ true ; for version 2.2G *
;* *
;****************************************************************
;
;
;****************************************************************
;* *
;* Set the following equate to false if a standard CP/M BIOS *
;* is desired. Set it to true for ZCPR3 buffer initialization *
;* *
zcpr3 equ true ; *
;* *
;****************************************************************
;
; Version 3.0
; Initial version customized for ZCPR3.
; John C. Smith July 23, 1984
;
; Version 3.1
; Added code to support ZCPR3 from floppy. Requires
; LDR SYS.RCP,SYS.ENV,SYS.FCP,NAMES.NDR be executed
; from the boot floppy. Path is changed to B$,B0
; when booted from floppy to be consistent with
; hard disk path of A$,A0. Also, added code and
; conditional equates to support CP/M versions 2.2D
; and 2.2G.
; John C. Smith August 5, 1984
;
zvers equ 31 ; ZCPR version number
;
;
.Z80 ; Z80 CPU
hdisk equ -1 ; -1 for hard disk, 0 for floppy
if zcpr3
msize equ 58 ; system memory size in k (ZCPR3)
else
msize equ 60 ; system memory size in k (CP/M)
endif
vers equ 22 ; CP/M version number
bias equ (msize-20)*1024 ; bias for systems larger than 20k
ccp equ 3400H+bias ; start of CCP
bdos equ ccp+806H ; start of BDOS (The resident portion of CP/M)
bios equ ccp+1600H ; start of Basic I/O Subsystem (BIOS)
cpml equ bios-ccp ; length of CP/M system in bytes (less BIOS)
nsects equ cpml/128 ; length of CP/M system in sectors (less BIOS)
if hdisk
trksec equ 68 ; sectors/track
else
trksec equ 40
endif
;
; ZCPR3 BUFFERS
;
WHEEL EQU 3EH ; LOCATION OF WHEEL BYTE
EXTPATH EQU 40H ; START OF EXTERNAL PATH
GRAF EQU 4FH ; LOCATION OF GRAPHICS BYTE
MCMD EQU 0F600H ; MUTLI-COMMAND BUFFER
;
;
;
bitport equ 14H ; status/control bit maped port
baudA equ 0 ; baud rate port (modem)
baudB equ 8 ; baud rate port (printer)
baud30 equ 05H ; 300 baud rate
iobyte equ 3 ; logical to physical map
rom equ 00000H ; base of rom
time equ 8000H ; time out rate
fox equ 0 ; set to 0
siokb0 equ 07H ; keyboard channel command/status
siosp0 equ 0EH ; serial printer command/status channel
siom0 equ 06H ; modem channel command/status
reset equ 18H ; channel reset
wr1 equ 01H ; interrupt enable and wait/ready modes
tid equ 00H ; transmitter interrupt disable
rid equ 00H ; recieve interrupt disable
wr3 equ 03H ; receiver logic control parameters
re equ 01H ; receiver enable
autoe equ 20H ; auto enable (use dcd and cts to enable recv
; and xmt
rbits8 equ 0C0H ; 8 bits/character
wr4 equ 04H ; control bits that affect both xmt and recv
sbits1 equ 04H ; 1 stop bit
cr16 equ 40H ; x16
wr5 equ 05H ; control bits that affect xmt
te equ 08H ; transmit enable
tbits8 equ 60H ; 8 bits/character
dtr equ 80H ; DTR output
pfdat equ 24 ; cent out data port (8 bit latch)
pstrob equ 3 ; bit in bit port
; aseg
; org bios
.phase bios
jp boot ; arrive here from cold start
jp wboot ; arrive here for warm start
jp const ; console status return in A FF=ready, 00=not
jp conin ; console char in
jp conout ; console char out
jp list ; listing char out
jp punch ; punch char out
jp reader ; reader char in
jp home ; move to track 0 on selected disk drive
jp seldsk ; select disk drive
jp settrk ; set track #
jp setsec ; set sector #
jp setdma ; set DMA address
jp read ; read selected sector
jp write ; write selected sector
jp listst ; list status (Ready to print a char)
jp sectran ; sector translate
ioconfig: defb 10000001B ; initial value for i/o byte (may be patched)
wrtsafe: defb 0 ; write safe flage 0=false
vtab: defb 11, 10, 8, 12 ; vector pad xlate table ^k ^j ^h ^l
defb '0', '1', '2', '3'
defb '4', '5', '6', '7'
defb '8', '9', 0 , 0
defb 0DH, '.'
baudrt: defb baud30 ; baud rate (modem)
defb baud30 ; baud rate (printer)
defb (sndtab-vtab)
sioint: ;i/o device initialization table
;first byte is number of bytes to send
;second byte is port to send out to
;third byte is data
;init sio channel for serial printer
defb 09H
defb siosp0
defb reset ;reset sio channel
defb wr4
defb sbits1 or cr16 ;one stop bit 16x clock
defb wr3
defb re or rbits8 or autoe ;recv enable, 8bits/char
defb wr5
defb te or tbits8 or dtr ;xmt enable, 8bits/char,assert dtr
defb wr1
defb tid or rid ;xmt & recv interrupts disabled
;init sio channel for modem
defb 09H
defb siom0
defb reset ;reset sio channel
defb wr4
defb sbits1 or cr16 ;one stop bit 16x clock
defb wr3
defb re or rbits8 or autoe ;recv enable, 8bits/char
defb wr5
defb te or tbits8 or dtr ;xmt enable, 8bits/char,assert dtr
defb wr1
defb tid or rid ;xmt & recv interrupts disabled
siotbnd:defb 0 ;end of table
sndtab: defb 0,0,0,0 ; up arrow key
defb 0,0,0,0 ; down arrow key
defb 0,0,0,0 ; left arrow key
defb 0,0,0,0 ; right arrow key
defb 0,0,0,0 ; 0 key on numeric pad
defb 0,0,0,0 ; 1 key on numeric pad
defb 0,0,0,0 ; 2 key on numeric pad
defb 0,0,0,0 ; 3 key on numeric pad
defb 0,0,0,0 ; 4 key on numeric pad
defb 0,0,0,0 ; 5 key on numeric pad
defb 0,0,0,0 ; 6 key on numeric pad
defb 0,0,0,0 ; 7 key on numeric pad
defb 0,0,0,0 ; 8 key on numeric pad
defb 0,0,0,0 ; 9 key on numeric pad
defb 'dir',0DH ; - key on numeric pad
defb 'swp',0DH ; , key on numeric pad
defb 0,0,0,0 ; <cr> " "
defb 0,0,0,0 ; . key on numeric pad
if versg
mdmflg: defb 0ffh ;Internal modem flag 0=none present
endif
subttl Cold and Warm boot entry points defb
page
; Cold boot entry point, set up system pointers and pass control to the CCP
boot: call diskint
xor a ; clear system disk number
ld (4),a
if zcpr3
LD (GRAF),A ; reset graphics byte
CPL
LD (WHEEL),A ; set wheel byte
LD HL,PATH ; initialize path
LD DE,EXTPATH
LD BC,7
LDIR
LD HL,CMD ; initialize multi-command line buffer
LD DE,MCMD
LD BC,0CH
LDIR
LD HL,0E600H ; initialize ZCPR3 RCP buffer by
LD A,8 ; filling memory with 0
CALL ZLOOP
endif
if zcpr3 and not hdisk ; if boot from floppy, initialize
LD HL,0F100H ; all other buffer spaces since
LD a,5 ; there will be no load from the
CALL ZLOOP ; "putovl" track.
endif
ld a,(ioconfig) ; init value for i/o byte
ld (iobyte),a
ld hl,sioint ; initialize i/o devices
iolp: ld b,(hl) ; number of bytes to send
inc hl
ld c,(hl) ; port to send
inc hl ; address of byte being sent
otir
ld a,(hl) ; get this byte
or a ; clean test
jr nz,iolp ; if more tables then do
if versd and hdisk
IN A,(BITPORT) ;2.2D PATCH
OR 4 ;2.2D PATCH
OUT (BITPORT),A ;2.2D PATCH
endif
ld a,(baudrt) ; set baud rates
out (baudA),a
ld a,(baudrt+1)
out (baudB),a
call print
defb 1AH, 0DH, 0AH
defb 'KAYPRO 10 '
defb msize/10+'0', msize mod 10+'0'
defb 'K CP/M Version '
defb vers/10+'0', '.', vers mod 10+'0'
if versd
defb 'D'
endif
if versf
defb 'F'
endif
if versg
defb 'G'
endif
if zcpr3
defb ' & ZCPR Version '
defb zvers/10+'0', '.', zvers mod 10+'0'
defb ' JCS'
endif
defb 0DH, 0AH, 00H
goccp: ld hl,time ; reset disk time out
ld (count),hl
ld a,0C3H ; set up CP/M jumps to bdos and wboot
ld hl,bios+3 ; wboot entry point
ld (0),a
ld (1),hl
ld hl,bdos ; entry point to bdos
ld (5),a
ld (6),hl
ld a,(4) ; last logical disk unit used
ld c,a
and 0FH ; valid disk?
cp 3
jp c,ccp
ld a,c ; no, so go to drive 0
and 0F0H
ld c,a ; pass to ccp to select
jp ccp ; pass control to ccp
; Warm boot entry point, re-load the CCP and BDOS
wboot:
if versg
ld a,(mdmflg)
cp 0
call nz,mdmnit
endif
ld c,0 ; select drive A:
call seldsk
call home
call diskint
call print
defb 0DH, 0AH, 'Warm Boot', 0DH, 0AH, 00H
wb0: ld sp,100H ; re-set stack
ld bc,0 ; set track
call settrk
ld bc,ccp ; first memory location to load
ld (dmaadr),bc
call setdma
ld bc,nsects*256+1
wb1: push bc ; save sector count and current sector
call setsec ; select sector
call read
pop bc
or a
jr nz,wb0 ; oops, error on warm boot
push bc
ld hl,(dmaadr) ; update dma address for next sector
ld de,128 ; new dma address
add hl,de
ld b,h
ld c,l
ld (dmaadr),hl
call setdma
pop bc
if not zcpr3
xor a
ld (ccp+7),a
endif
dec b
jp z,goccp ; done loading
inc c ; bump sector count
if not hdisk
ld a,trksec ; next track?
cp c
jr nz,wb1
ld c,16 ; next sector to read
push bc
ld c,1
call settrk ; set track number
pop bc
endif
jr wb1
subttl logical to physical devices CON:, PUN:, RDR:, and LST:
page
; logical devices are con: rdr: pun: and lst:
; physical devices are:
; crt: video and kbd
; tty: serial
; lpt: centronics
; ul1: serial with cts as busy
; pun: same as ul1
;
;con: tty, crt
;rdr: tty
;pun: tty, pun
;lst: tty, crt, lpt, ul1
const: ld hl,(count) ; time out motors?
dec hl
ld (count),hl
ld a,h
or l
call z,diskoff
ld a,(cnt) ;load function counter
or a ;clean test
jr nz,loadup ;set to do function if not 0
ld a,(iobyte) ; get i/o byte
and 03H ; strip to con bits
ld l,rom+33H ; serial status
jp z,callrom
ld l,rom+2AH ; assume CRT
jp callrom
loadup: ld a,0ffh ;set for get character
or a ;clean test
ret
conin: call const ; key press?
or a
jr z,conin
ld a,(cnt) ;get counter value
or a ;clean test
jr nz,frjp ;do function if not 0
ld a,(iobyte) ; go get character
and 03H ; check i/o byte
ld l,rom+36H ; serial input
jp z,callrom
ld l,rom+2DH ; assume input from kbd
call callrom ; go get char
or a
ret p ; msb not set
and 01FH ; form table index to vtab
ld hl,vtab
ld c,a
ld b,0
add hl,bc
ld a,(hl) ; pick up xlated character
or a ; clean test
ret nz ; if valid character value return
sectab: ld hl,sndtab ;set to new table value
ld a,c ;get character position
sla a ;shift left to
sla a ;mult by 2, again
ld c,a ;get new character position
add hl,bc ;set hl to character position
ld (pntr),hl ;store position in pointer
ld a,4 ;set to this value
ld (cnt),a ;initialize counter to 4
;continue process of function
frjp: ld hl,(pntr) ;get pointer value
ld c,(hl) ;load character into c reg
inc hl ;increment pointer
ld (pntr),hl ;save this value off
ld a,(cnt) ;retrieve current counter value
dec a ;decrement this value
ld (cnt),a ;save this value off
ld a,c ;move character into a
ret z ;return if zero
ld a,(hl) ;get next byte value
cp fox ;compare to 0
ld a,c ;move value in c to a
ret nz ;return if not zero
xor a ;clear accumulator
ld (cnt),a ;clear counter value
ld a,c ;move value in c to a
ret
diskoff:ld l,rom+27H
jp callrom
conout:
if zcpr3
LD A,(GRAF) ; check graphics byte
OR A ; is it set?
JR NZ,R1 ; allow eighth bit if it is
LD A,C ; otherwise, mask it out
AND 7FH
LD C,A
R1:
endif
ld a,(iobyte) ; check i/o byte
and 03H
ld l,rom+39H ; serial output
jp z,callrom
ld l,rom+45H ; assume video
jp callrom
reader: ld l, rom+36H ; serial input
jp callrom
;punch: ld a,(iobyte) ; check i/o byte
; and 30H
; ld l,rom+39H ; serial punch
; jp z,callrom
; ld l, rom+42H ; serial with cts as busy
; jp callrom
punch:
ld l,rom+39h ;serial punch
jp callrom
;
list: ld a,(iobyte)
and 0C0H ; check i/o byte
ld l,rom+39H ; serial
jp z,callrom
cp 80H ; centronics
jp z,lstdev ; time delay routine for output
ld l,rom+45H ; video
cp 40H
jp z,callrom
; ld l, rom+42H ; assume serial with cts as busy
ld l, rom+39h ;ul1: default to serial
jp callrom
listst: ld a,(iobyte) ; check i/o byte
and 0C0H
ld l,rom+42H ; serial
jp z,callrom
ld l,rom+3CH ; centronics
cp 80H
jp z,callrom
xor a ; 0=ready
ret
lstdev: call listst ; is printer busy
jr nz,lstdev ; if not return
ld a,c ; move character into a
out (pfdat),a ; output character to printer
in a,(bitport) ; strb. printer
res pstrob,a
out (bitport),a
set pstrob,a
out (bitport),a
ret
if versg
mdmnit: ld a,0fh ; set up pio
out (23h),a
ld a,87h ; and interrupt vector
out (23h),a
ld a,4ah ; set modem on-hook
out (21h),a
endif
subttl Disk I/O and ROM dispatch
page
diskint:ld l,rom+03H ; re-set disk software sub-system
jr callrom
home: ld l,rom+0CH ; home disk drive rom routine
jr callrom
seldsk: ld l,rom+0FH ; select disk drive
jr callrom
settrk: ld l,rom+12H ; seek track
jr callrom
setsec: ld l,rom+15H ; set sector number
jr callrom
setdma: ld l,rom+18H ; set dma address
jr callrom
read: ld hl,time ; reset time out
ld (count),hl
ld l,rom+1BH ; read a logical sector
jr callrom
write: ld hl,time ; reset time out
ld (count),hl
ld l,rom+1EH ; write a logical sector
ld a,(wrtsafe) ; write safe flag
or a ; true or false
jr z,callrom ; normal operation
ld c,1 ; directory write code (forces write op)
jr callrom
sectran:ld l,rom+21H ; xlate logical to physical sector
jr callrom
callrom:exx ; save cp/m arguments
in a,(bitport) ; turn rom on
set 7,a
out (bitport),a
ld (savsp),sp ; save current stack (may be under rom)
ld sp,stack ; set a local stack
ld de,biosret ; rom to "RET" here
push de
exx ; restore cp/m arguments and call loc
ld h,0
jp (hl) ; to rom routine specified in hl
biosret:ex af,af' ; save reg A
ld sp,(savsp) ; restore stack
in a,(bitport) ; off the rom
res 7,a
out (bitport),a
ex af,af' ; restore reg A
ret ; done with rom routine
print:
ex (sp),hl ; pop return address, points to text to print
ld a,(hl) ; get a byte of text, stop on zero byte
inc hl
ex (sp),hl ; save new return address
or a ; is it a zero byte?
ret z
ld c,a ; no, so print it
call conout
jr print
if zcpr3
ZLOOP: LD B,0FFH
ZERO: LD (HL),0
INC HL
DJNZ ZERO
DEC A
JR NZ,ZLOOP
RET
endif
if hdisk and zcpr3
PATH: DEFB 1,'$',1,0,0,0,0,0,0,0,0 ; search path
else
PATH: DEFB 2,'$',2,0,0,0,0,0,0,0,0
endif
if zcpr3
CMD: DEFB 4,0F6H,0C8H,0,'STARTUP',0 ; mcl buffer
pntr: defw 0 ; pointer for function key routine
cnt: defb 0 ; character counter for function routine
count: defs 2 ; disk time out counter
savsp: defs 2 ; current spact pointer during rom call
dmaadr: defs 2 ; dma address for warm boot
db 'END' ; end of BIOS marker
stack equ $+64 ; a local stack
else
; Patch CCP to display user # and search user 0 for a COM file.
openf equ 15 ; open disk function
bdosent equ 5 ; entry point to bdos
ccperr equ ccp+7EEH
ccpfcb equ ccp+7CDH
ccpco equ ccp+8CH
ccpread equ ccp+0F9H
ccpp1 equ ccp+0392H
ccpp2 equ ccp+00D7H
ccpp3 equ ccp+06E9H
getusr macro x
.xlist
ld e,-1
ld c,32
call bdosent
ld (x),a
.list
endm
setusr macro x
.xlist
ld a,(x)
ld e,a
ld c,32
call bdosent
.list
endm
p1: ld c,32 ; show user#, get current one
ld e,-1 ; e=255 is get user code
call bdosent
cp 10 ; if a>10 then print first digit
jr c,pmt0
sub 10
push af ; save second digit
ld a,'1'
call ccpco
pop af
pmt0: add a,'0' ; for ascii digit
call ccpco
ld a,'>'
pmt2: jp ccpco
p2: getusr curuser
ld (fcbuser),a
ld de,ccpfcb
ld c,openf ; open a file (check user 0 if not found)
call bdosent
ld (ccperr),a
inc a
ret nz ; nz=file opened
ld a,(curuser) ; get current user #
or a
jr z,nogd ; in user 0, file open no good
xor a
ld (fcbuser),a ; try user 0
setusr fcbuser
ld de,ccpfcb ; try to open file
ld c,openf
call bdosent
ld (ccperr),a ; ccp error return
setusr curuser ; restore user #
nogd: ld a,(ccperr) ; was open ok?
inc a
ret ; back to ccp
p3: setusr fcbuser ; read a sector
ld de,ccpfcb
call ccpread
push af
setusr curuser
pop af
ret
pntr: defw 0 ; pointer for function key routine
cnt: defb 0 ; character counter for function routine
curuser:defs 1 ; current user
fcbuser:defs 1 ; user # of load file
count: defs 2 ; disk time out counter
savsp: defs 2 ; current spact pointer during rom call
dmaadr: defs 2 ; dma address for warm boot
stack equ $+64 ; a local stack
endif
end