title 'revised KAYPRO 4-83 DOS+/CPM2 BIOS (86/10/31)' ;################################################################# ;## KAYPRO CBIOS for CP/M 2.2 ## ;## Copyright (C) 1982 By Non-Linear Systems, Inc. ## ;## No warranty is made, expressed or implied. ## ;################################################################# ;## Last Update: july 7,1982 [001] ## ;## by jim Nickerson (Kaypro 2) ## ;## changes: ## ;## -allow redefinition of kpd in cbios ## ;## -change to allow test of serial on liststatus ## ;## -default ul1: to tty on list ## ;################################################################# ;## Updated to match KAYPRO 4 bios, 83/10/1, cbf ## ;################################################################# ;## Revised for double console, more stack, correct lsta, ## ;## avoid use of primed registers for future interrupts. ## ;## Anomalous connection to CCP eliminated. dmadr/ram remains. ## ;## "Warm boot" message eliminated. Boot error resets disks. ## ;## Disk shutdown when using list, reader, etc. ## ;## remote console with interrupt. ul1=crt on lst: 84/3/9 cbf ## ;## by C.B.Falconer, 680 Hartford Tpk, Hamden Ct. (203)281-1438 ## ;################################################################# ;## "gorom" now passes iobyte in (l). Future systems can thus ## ;## implement device selection entirely in ROM. New entries ## ;## must be made for cin,cout,csta,rin,pout,lout,lsta, and for ## ;## psta and rsta for future plans. After this bios can shrink ## ;################################################################# ;## (2) rev 85/01/06 to preserve (bc) across rom calls, and so ## ;## that the "rem" device allows mixed remote and kbd input. ## ;## Rem operation now halted with an 08Eh from keyboard, which ## ;## is only available with the "uniqkeys" table configuration. ## ;## (i.e. no translation at all). This comes from numpad "-". ## ;## All this provides the fundamental groundwork for RCPM and ## ;## BBS operation. Rem can be stopped by altering iobyte also. ## ;## Also removed anomalous connection to RAM storage. This is ## ;## carefully packed so the start-up message works on the orig- ## ;## inal ROM. Any extra length fouls it. With NEWROM mounted ## ;## vout returns current cursor pos'n in hl, and home returns ## ;## pointer to disk system info (last errors/soft count). cbf ## ;################################################################# ;## (3) rev 86/10/06 to initialize a wheel and PATH on cold ## ;## boot for DOS+. Allow function keys 92h up. cbf ## ;################################################################# ;## (4) rev 86/10/31 for "nul" device 3 on lister. lsta=true. ## ;################################################################# ;## 86/12/07 No change. DOS+ ver equate becomes 25 ## ;################################################################# ; ; Works for M80 and SLRMAC INCLUDE Z80.LIB ; bver equ 4; cbf bios version vers equ 25; CPM/DOS+ version number ccpsz equ 0800h; size of CCP (can change independant) bdossz equ 0E00h; size of BDOS cpml equ ccpsz+bdossz; lgth of CP/M sys (bytes, less BIOS) nsects equ cpml/128; lgth of CP/M sys (sector, less BIOS) ; iobyte equ 3; logical to physical map ; and initial usr/drv at iobyte+1 ; ; SYSTEM DEPENDANT values trksec equ 40; sectors/track. bauda equ 0; control kbd baud rate msize equ 63; system memory size in k. Elim later ; (I install RAMDSK above bios) ; KAYPRO DEPENDANT values bitpt equ 1CH; status/control bit mapped port @wheel equ 045h; And PATH at @wheel +1 rom equ 00000H; base of rom ram equ 0FC00H; scratch ram ; cr equ 0dh lf equ 0ah clear equ 01ah; Clear Kaypro crt screen brk equ ('N' and 03fh) + 080h; "REM" breakin char. ; ; ; *** CODE BEGINS, bios vector *** bios: jmp boot; <00> arrive here from cold start jmp wboot; <01> arrive here for warm start jmp const; <02> console status return in A ; FF=ready, 00=not jmp conin; <03> console char in jmp cout; <04> console char out jmp list; <05> listing char out jmp punch; <06> punch char out jmp rin; <07> reader char in jmp home; <08> move to tk0 on selected dsk drv jmp seldk; <09> select disk drive jmp setrk; <10> set track # jmp setsec; <11> set sector # jmp setdma; <12> set DMA address jmp read; <13> read selected sector jmp write; <14> write selected sector jmp lsta; <15> list status (Rdy for a char) jmp xltsec; <16> sector translate ; ; defaults to be loaded ; These occupy the space for extended bios calls 17 thru 23 iobgn: db 10000001B; initial value for i/o byte ; (may be patched) wtsafe: db 0; write safe flag, 0=false vtab: db 11, 10, 8, 12; vector pad xlate table ^k ^j ^h ^l db '0', '1', '2', '3' db '4', '5', '6', '7' db '8', '9', brk, ','; Set intercept for REM db cr, '.'; last on 091h key code bdbgn: db 7; initial serial port baud rate. ; 5,6,7,10,12,14 correspond to 300, ; 600,1200,2400,4800,9600 baud. ; ; add any extended bios calls here, #24 up. This should preserve ; compatibility with Kaypro normal software. ; ; if only these were standard CP/m items. Portable communications jmp sistat; (24) Reader status jmp sostat; (25) Punch status jmp romhl; (26) GP rom system connector ; calls rom address (hl), passing ; a,b,c,d,e, returns a,f,d,e,h,l ; preserving bc ; ; logical devices are con: rdr: pun: and lst: ; physical devices are: ; crt: video and kbd ; tty: serial ; lpt: centronics ; dbl: video and lst device ; rem: video and tty (remote opn with CRT monitor) ; kbd mixes with serin, can stop rem operation ; nul: Discards output, always ready ; ;con: tty, crt, rem, dbl ;rdr: tty (all assignments) ;pun: tty (all assignments) ;lst: tty, crt, lpt, nul ; ; check for local character and interuption. preserve (bc) chkhlt: call ksta rz; no local char call kbdin cpi brk rnz; not interrupted ; " " ; shut down "rem" operation lxi h,iobyte; Must have been 2 in con field dcr m; set back to "crt" ori 07fh; return a rub in case input ret; with nz to exit remin ; conin: call dkoff; Immediate shut down on operator wait lda iobyte ani 03H; check i/o byte jrz serin; 0, serial rar jrnc remin; 2, remote input ; " " 1,3 keyboard input kbdin: mvi l,rom+2DH call gorom; go get char ora a rp; msb not set ; " " ; Translate kbd char (80h..91h) via system table cpi 092h; form table index to vtab rnc; do not xlate. Allows extra keys lxi h,vtab+080h add l mov l,a; discard carry to index table mov a,m; pick up xlated character ret ; cout: lda iobyte; check i/o byte ani 03H jrz serout; 0, serial dcr a jrz vout; 1, crt push psw call vout; 2,3 video out pop psw; (iobyte.con)-1 rar jrc remout; (2-1)=rem ; " " 3=dbl, do listout list: lda iobyte ani 0C0H; check i/o byte jrz serout; 0, serial mvi l,rom+3FH; centronics cpi 80H jrz gorom; 2, centronics rnc; 3, nul device ; " " 1, use video ; Output to CRT screen only. Escapes etc apply vout: mvi l,rom+45H; video jr gorom; 1,3 default to video ; lsta: lda iobyte; check i/o byte ani 0C0H jrz sostat; 0, serial cpi 80H jrz ppstat; 2, centronics port ; " " 1,3 video, nul is ready ; return (a) = 0ffh with nz flag ori 0ffh ret ; sostat: mvi l,rom+042h; serial port output status jr gorom ; ppstat: mvi l,rom+3ch; centronics call gorom; Fix bad original ROM return value rnz; ; " " ; Return (a) = 0 with zero flag xra a ret ; sistat: mvi l,rom+033h; serial port input status jr gorom ; ; get char from remote terminal or local keyboard. ; Any local char. = brk interrupts (- on num pad with config) remin: call chkhlt; check for local halt rnz; a local char in interrupted call sistat; do not get hung in ROM routines, jrz remin; wait for char. ready ; " " ; reader input/serial with disk turn off rin: call dkoff; during wait for peripheral serin: mvi l,rom+36H; serial input jr gorom ; const: lda iobyte; get i/o byte rar; strip to con bits jrc ksta; 1,3 CRT input rar jrnc sistat; 0, TTY call sistat; 2, REM rnz; have something ; " " else check keyboard ksta: mvi l,rom+2AH jr gorom; keyboard status ; ; char. to remote terminal, any local char. interrupts ; only called from conout set for con:=rem: remout: call chkhlt; may inhibit further rem opn ; " " echo on remote terminal punch: serout: mvi l,rom+39h; serial punch ; " " ; transfer control to rom bank at (l). Switch stack ; The a,f,b,c,d,e registers are passed to the ROM routines and ROM ; routine exit registers a,f,d,e,h,l are returned. Rewritten to avoid ; disturbing the primed registers and to pass all registers except hl, ; sp so that interrupt driven systems can co-exist. (bc) preserved. ; (l) is used to pass iobyte, thus making it visible in the ROM. The ; ROM system can then perform the complete device allocation. ; Note that ROM operation is non-reentrant, because of stack. gorom: mvi h,0; all rom entries in page zero ; " " ; Entry here can call any Rom addr, pass abcde, rtn afdehl, save bc romhl: di; No interrupts during stk manipulation push b; save thru rom call sspd savsp; save current stack (may be under rom) lxi sp,romret; Set return for ROM routines sspd stktop; at top of local stack lxi sp,stktop; and switch to the local stack ; ** USING LOCAL STACK ** push h; set execution point on stack push psw; useless save at present. lxi h,mtime inr m cz dkoff; timed out disk motors lhld iobyte; in (l), default disk id in (h) in bitpt; turn rom on ori 080h; set bit 7 out bitpt; now 0..3fffh is a new bank pop psw; pass input (a) ei ret; rom routine specified on TOS romret: push psw; save returned (a) in bitpt; off the rom ani 07fh; clear bit 7 out bitpt pop psw; restore reg A ; ** END LOCAL STACK USE ** lspd savsp; restore stack pop b; restore entry value ret; done with rom routine ; dkini: mvi l,rom+03H; re-set disk software sub-system jr gorom ; home: mvi l,rom+0CH; home disk drive rom routine jr gorom ; seldk: mvi l,rom+0FH; select disk drive jr gorom ; setrk: mvi l,rom+12H; seek track jr gorom ; setsec: mvi l,rom+15H; set sector number jr gorom ; setdma: mvi l,rom+18H; set dma address jr gorom ; read: mvi l,rom+1BH; read a logical sector ; " " ; a disk read/write operation (via (l)) rdwrt: xra a sta mtime; reset disk motor time-out jr gorom ; xltsec: mvi l,rom+21H; xlate logical to physical sector jr gorom ; write: mvi l,rom+1EH; write a logical sector lda wtsafe; write safe flag ora a; true or false jrz rdwrt; normal operation mvi c,1; directory write code (forces write op) jr rdwrt ; ; shut down disk drive motors dkoff: in bitpt ori 040h out bitpt ret ; ; Warm boot entry point, re-load the CCP and BDOS ; Uses 8 bytes below 0100h for stack operations. wboot: call dkini lxi sp,100H; re-set stack mvi c,0; select drive A: call seldk lxi b,nsects*256+1; (b)=num to do; (c)=sector # lxi h,bios-cpml-128; first mem loc (-128) to load push h push b lxi b,0; set track wboot1: call setrk pop b; get sector/trk setting wboot2: call setsec; select sector pop h push b lxi b,128; This modification is to avoid dad b; the anomalous connection to mov b,h; RAM storage area in the mov c,l; original, which prevents free call setdma; ROM modification. cbf 85/1/6 mov h,b mov l,c pop b push h call read ora a jrnz wboot; error on warm boot. CHECK DISKS mvi a,3; Use warm ccp entry dcr b; Sequence allows 1 track boot (dd) jrz goccp; done loading. Stack will be ignored inr c; bump sector count mvi a,trksec; on to next track? cmp c jrnz wboot2 mvi c,16; first sector on next track push b; save counters lxi b,1 jr wboot1 ; ; Set the CP/m vectors, and enter the CCP ; (a) = 0 for cold load, (a) = 3 for warm boot ; there may be anomalous garbage on the stack, ccp resets. goccp: lxi h,bios+3; wboot entry point shld 1 lxi h,bios-bdossz+6; entry point to bdos shld 6 lxi h,bios-cpml mov l,a; Warm/cold entry mvi a,0C3H; set up CP/M jumps to bdos and wboot sta 0 sta 5 lda 4; last logical disk unit used mov c,a; pass to ccp to select pchl; pass control to ccp ; ; Cold boot entry point, set up sys pointers, pass control to CCP ; **** This space is re-usable as stack after a cold boot **** boot: call dkini; purpose is to set RAM access lhld iobgn; junk into h mvi h,0 shld iobyte; init iobyte, system disk number mvi l,0ffh; wheel on shld @wheel; init wheel, set path to empty lda bdbgn out bauda; set initial serial baud lxi h,mesg boot1: push h mov c,m; 1st char. known non-null call vout pop h; Prevent any stack overflow destroying inx h; code until after overwriting "mesg" mov a,m; Somewhere a null will be found ora a; in such a case. Present ROM ok. jrnz boot1; more jr goccp; (a) is zero, cold entry ; ; NOT enough room for this - Use later when ROM upgraded ; for automatic size info on sign on without special MOVCPM cases ; eliminates all need for the MSIZE parameter, and postpones ; all customization to link/relocation time. ;show: pop h ; push h; get calling point - indicates mem size ; mov a,h ; adi 5; form no. of Ks ; rar; assumes no extra pieces ; rar; to set extra carries ; mvi c,'0'-1; if so extract and list as /n (n=1..3) ;show1: inr c ; sub a,10 ; jr p,show1; convert to 2 decimal digits ; adi 10 ; push psw ; call vout ; pop psw ; mov c,a ; jmp vout ; mesg: db clear, msize/10+'0', msize mod 10+'0' db 'k DOS+' db vers/10+'0', '.', vers mod 10+'0' db ' KP4(f', bver + '0', ')',0 ; The final nul must appear before 1f7 from the start of ; the bios, for the message to appear correctly with the ; original issue Kaypro 4 (83) ROM. For NEWROM this is 1f1 ; used equ $-bios; Max value 01f7 or 1f1, see above ds 507-used,0; ",0" to ensure null fill stktop: ds 2,0; a local stack with a return address savsp: ds 2,0; stack pointer during rom call mtime: ds 1,0; control disk motor time-out ; end