home *** CD-ROM | disk | FTP | other *** search
- title 'Root module of relocatable BIOS for CP/M 3.0 28 Aug 85'
-
- ; version 1.0 5 Sept 84
-
-
- maclib cxequ ; C128 equates lib
-
- maclib modebaud ; define mode bits
-
- maclib Z80
-
- ; Copyright (C), 1982
- ; Digital Research, Inc
- ; P.O. Box 579
- ; Pacific Grove, CA 93950
- ;
- ;
- ; This is the invariant portion of the modular BIOS and is
- ; distributed as source for informational purposes only.
- ; All desired modifications should be performed by
- ; adding or changing externally defined modules.
- ; This allows producing "standard" I/O modules that
- ; can be combined to support a particular system
- ; configuration.
-
- bell equ 7
- ctlQ equ 'Q'-'@'
- ctlS equ 'S'-'@'
-
- ccp equ 0100h ; Console Command Processor
- ; gets loaded into the TPA
-
- page
-
- cseg ; GENCPM puts CSEG stuff in
- ; common memory
-
- ; variables in system data page
-
- extrn @covec,@civec
- extrn @aovec
- extrn @aivec,@lovec ; I/O redirection vectors
- extrn @mxtpa ; addr of system entry point
- extrn @bnkbf ; 128 byte scratch buffer
-
- ; initialization
-
- extrn ?init ; general initialization and signon
- extrn ?ldccp,?rlccp ; load & reload CCP for BOOT & WBOOT
-
- ; user defined character I/O routines
-
- extrn ?ci,?co,?cist,?cost ; each take device in <B>
- extrn ?cinit ; (re)initialize device in <C>
- extrn @ctbl ; physical character device table
-
- ; disk communication data items
-
- extrn @dtbl ; table of pointers to XDPHs
-
- ; memory control
-
- extrn ?xmove,?move ; select move bank, and block move
- extrn ?bank ; select CPU bank
-
- ; clock support
-
- extrn ?time ; signal time operation
-
- ;; user function
-
- extrn ?user ; special functions
-
- ; general utility routines
-
- public ?pmsg ; print message
- public ?pdec ; print number from 0 to 65535
- public ?pderr ; print BIOS disk error message header
-
-
- page
-
- ; External names for BIOS entry points
-
- public ?boot,?wboot,?const,?conin,?cono,?list,?auxo,?auxi
- public ?home,?sldsk,?sttrk,?stsec,?stdma,?read,?write
- public ?lists,?sctrn
- public ?conos,?auxis,?auxos,?dvtbl,?devin,?drtbl
- public ?mltio,?flush,?mov,?tim,?bnksl,?stbnk,?xmov
-
-
- ; BIOS Jump vector.
- ;
- ; All BIOS routines are invoked by calling these
- ; entry points.
-
- ?boot: jmp boot ; initial entry on cold start
- ?wboot: jmp wboot ; reentry on program exit, warm start
-
- ?const: jmp const ; return console input status
- ?conin: jmp conin ; return console input character
- ?cono: jmp conout ; send console output character
- ?list: jmp list ; send list output character
- ?auxo: jmp auxout ; send auxilliary output character
- ?auxi: jmp auxin ; return auxilliary input character
-
- ?home: jmp home ; set disks to logical home
- ?sldsk: jmp seldsk ; select disk drive, return disk parameter info
- ?sttrk: jmp settrk ; set disk track
- ?stsec: jmp setsec ; set disk sector
- ?stdma: jmp setdma ; set disk I/O memory address
- ?read: jmp read ; read physical block(s)
- ?write: jmp write ; write physical block(s)
-
- ?lists: jmp listst ; return list device status
- ?sctrn: jmp sectrn ; translate logical to physical sector
-
- ?conos: jmp conost ; return console output status
- ?auxis: jmp auxist ; return aux input status
- ?auxos: jmp auxost ; return aux output status
- ?dvtbl: jmp devtbl ; return address of device def table
- ?devin: jmp ?cinit ; change baud rate of device
-
- ?drtbl: jmp getdrv ; return address of disk drive table
- ?mltio: jmp multio ; set multiple record count for disk I/O
- ?flush: jmp flush ; flush BIOS maintained disk caching
-
- ?mov: jmp ?move ; block move memory to memory
- ?tim: jmp ?time ; Signal Time and Date operation
- ?bnksl: jmp bnksel ; select bank for code execution
- ; and default DMA
- ?stbnk: jmp setbnk ; select different bank for disk
- ; I/O DMA operations.
- ?xmov: jmp ?xmove ; set source and destination banks
- ; for one operation
-
- jmp ?user ; reserved for future expansion
- jmp 0 ; reserved for future expansion
- jmp 0 ; reserved for future expansion
-
- page
- ;
- ; BOOT
- ; Initial entry point for system startup.
-
- dseg ; this part can be banked
- boot:
- lxi sp,boot$stack
- mvi c,15 ; initialize all 16 character devices
- c$init$loop:
- push b
- call ?cinit
- pop b
- dcr c
- jp c$init$loop
-
- call ?init ; perform any additional system initialization
- ; and print signon message
- lxi b,16*256+0
- lxi h,@dtbl ; init all 16 logical disk drives
- d$init$loop:
- push b ; save remaining count and abs drive
- mov e,m
- inx h
- mov d,m
- inx h ; grab @drv entry
- mov a,e
- ora d
- jrz d$init$next ; if null, no drive
-
- push h ; save @drv pointer
- xchg ; XDPH address in <HL>
- dcx h
- dcx h
- mov a,m
- sta @RDRV ; get relative drive code
- mov a,c
- sta @ADRV ; get absolute drive code
- dcx h ; point to init pointer
- mov d,m
- dcx h
- mov e,m ; get init pointer
- xchg
- call ipchl ; call init routine
- pop h ; recover @drv pointer
- d$init$next:
- pop b ; recover counter and drive #
- inr c
- djnz d$init$loop ; and loop for each drive
- jmp boot$1
-
- cseg ; following in resident memory
- boot$1:
- call set$jumps
- call ?ldccp ; fetch CCP for first time
- jmp ccp
-
- page
-
- ; WBOOT
- ; Entry for system restarts.
-
- wboot:
- lxi sp,boot$stack
- call set$jumps ; initialize page zero
- call ?rlccp ; reload CCP
- jmp ccp ; then reset jmp vectors and exit to ccp
-
-
- set$jumps:
-
- if banked
- mvi a,1
- call ?bnksl
- endif
-
- mvi a,JMP
- sta 0
- sta 5 ; set up jumps in page zero
- lxi h,?wboot
- shld 1 ; BIOS warm start entry
- lhld @MXTPA
- shld 6 ; BDOS system call entry
- ret
-
-
- ds 64
- boot$stack equ $
-
- page
- ;
- ; DEVTBL
- ; Return address of character device table
- devtbl:
- lxi h,@ctbl
- ret
-
- ;
- ; GETDRV
- ; Return address of drive table
- getdrv:
- lxi h,@dtbl
- ret
-
-
- ;
- ; CONOUT
- ; Console Output. Send character in <C>
- ; to all selected devices
- conout:
- lhld @covec ; fetch console output bit vector
- jmp out$scan
-
-
- ;
- ; AUXOUT
- ; Auxiliary Output. Send character in <C>
- ; to all selected devices
- auxout:
- lhld @aovec ; fetch aux output bit vector
- jmp out$scan
-
-
- ;
- ; LIST
- ; List Output. Send character in <C>
- ; to all selected devices.
- list:
- lhld @lovec ; fetch list output bit vector
-
- out$scan:
- mvi b,0 ; start with device 0
- co$next:
- dad h ; shift out next bit
- jrnc not$out$device
- push h ; save the vector
- push b ; save the count and character
- not$out$ready:
- call coster
- ora a
- jrz not$out$ready
- pop b
- push b ; restore and resave the character and device
- call ?co ; if device selected, print it
- pop b ; recover count and character
- pop h ; recover the rest of the vector
- not$out$device:
- inr b ; next device number
- mov a,h
- ora l ; see if any devices left
- jrnz co$next ; and go find them...
- ret
-
- page
- ;
- ; CONOST
- ; Console Output Status. Return true if
- ; all selected console output devices
- ; are ready.
- conost:
- lhld @covec ; get console output bit vector
- jr ost$scan
-
-
- ;
- ; AUXOST
- ; Auxiliary Output Status. Return true if
- ; all selected auxiliary output devices
- ; are ready.
- auxost:
- lhld @aovec ; get aux output bit vector
- jr ost$scan
-
-
- ;
- ; LISTST
- ; List Output Status. Return true if
- ; all selected list output devices
- ; are ready.
- listst:
- lhld @lovec ; get list output bit vector
-
- ost$scan:
- mvi b,0 ; start with device 0
- cos$next:
- dad h ; check next bit
- push h ; save the vector
- push b ; save the count
- mvi a,0FFh ; assume device ready
- cc coster ; check status for this device
- pop b ; recover count
- pop h ; recover bit vector
- ora a ; see if device ready
- rz ; if any not ready, return false
- inr b ; drop device number
- mov a,h
- ora l ; see if any more selected devices
- jrnz cos$next
- ori 0FFh ; all selected were ready, return true
- ret
-
- coster: ; check for output device ready,
- ; including optional xon/xoff support
- mov l,b
- mvi h,0 ; make device code 16 bits
- push h ; save it in stack
- dad h
- dad h ; create offset into device
- dad h ; characteristics tbl
- lxi d,@ctbl+6
- dad d ; make address of mode byte
- mov a,m
- ani mb$xonxoff
- pop h ; recover console number in <HL>
- jz ?cost ; not a xon device, go get output status direct
- lxi d,xofflist
- dad d ; make pointer to proper xon/xoff flag
- call cist1 ; see if this keyboard has character
- mov a,m
- cnz ci1 ; get flag or read key if any
- cpi ctlq
- jrnz not$q ; if its a ctl-Q,
- mvi a,0FFh ; set the flag ready
- not$q:
- cpi ctls
- jrnz not$s ; if its a ctl-S,
- mvi a,00h ; clear the flag
- not$s:
- mov m,a ; save the flag
- call cost1 ; get the actual output status,
- ana m ; and mask with ctl-Q/ctl-S flag
- ret ; return this as the status
-
- cist1: ; get input status with <BC> and <HL> saved
- push b
- push h
- call ?cist
- pop h
- pop b
- ora a
- ret
-
- cost1: ; get output status, saving <BC> & <HL>
- push b
- push h
- call ?cost
- pop h
- pop b
- ora a
- ret
-
- ci1: ; get input, saving <BC> & <HL>
- push b
- push h
- call ?ci
- pop h
- pop b
- ret
-
- page
- ;
- ; CONST
- ; Console Input Status. Return true if
- ; any selected console input device
- ; has an available character.
- const:
- lhld @civec ; get console input bit vector
- jr ist$scan
-
-
- ;
- ; AUXIST
- ; Auxiliary Input Status. Return true if
- ; any selected auxiliary input device
- ; has an available character.
- auxist:
- lhld @aivec ; get aux input bit vector
-
- ist$scan:
- mvi b,0 ; start with device 0
- cis$next:
- dad h ; check next bit
- mvi a,0 ; assume device not ready
- cc cist1 ; check status for this device
- ora a
- rnz ; if any ready, return true
- inr b ; drop device number
- mov a,h
- ora l ; see if any more selected devices
- jrnz cis$next
- xra a ; all selected were not ready, return false
- ret
-
- page
- ;
- ; CONIN
- ; Console Input. Return character from first
- ; ready console input device.
- conin:
- lhld @civec
- jr in$scan
-
-
- ; AUXIN
- ; Auxiliary Input. Return character from first
- ; ready auxiliary input device.
- auxin:
- lhld @aivec
-
- in$scan:
- push h ; save bit vector
- mvi b,0
- ci$next:
- dad h ; shift out next bit
- mvi a,0 ; insure zero a (nonexistant device not ready).
- cc cist1 ; see if the device has a character
- ora a
- jrnz ci$rdy ; this device has a character
- inr b ; else, next device
- mov a,h
- ora l ; see if any more devices
- jrnz ci$next ; go look at them
- pop h ; recover bit vector
- jr in$scan ; loop til we find a character
-
- ci$rdy:
- pop h ; discard extra stack
- jmp ?ci
-
- page
-
- ; Utility Subroutines
-
-
- ?pmsg: ; print message @<HL> up to a null
- ; saves <BC> & <DE>
- push b
- push d
- pmsg$loop:
- mov a,m
- ora a
- jrz pmsg$exit
- mov c,a
- push h
- call ?cono
- pop h
- inx h
- jr pmsg$loop
- pmsg$exit:
- pop d
- pop b
- ret
-
- ?pdec: ; print binary number 0-65535 from <HL>
- lxi b,table10
- lxi d,-10000
- next:
- mvi a,'0'-1
- pdecl:
- push h
- inr a
- dad d
- jrnc stoploop
- inx sp
- inx sp
- jr pdecl
- stoploop:
- push d
- push b
- mov c,a
- call ?cono
- pop b
- pop d
- nextdigit:
- pop h
- ldax b
- mov e,a
- inx b
- ldax b
- mov d,a
- inx b
- mov a,e
- ora d
- jrnz next
- ret
-
- table10:
- dw -1000,-100,-10,-1,0
-
-
- ?pderr:
- lxi h,drive$msg
- call ?pmsg ; error header
- lda @adrv
- adi 'A'
- mov c,a
- call ?cono ; drive code
- lxi h,track$msg
- call ?pmsg ; track header
- lhld @trk
- call ?pdec ; track number
- lxi h,sector$msg
- call ?pmsg ; sector header
- lhld @sect
- jr ?pdec ; sector number (call/ret)
-
-
- ;
- ; BNKSEL
- ; Bank Select. Select CPU bank for further execution.
- bnksel:
- sta @cbnk ; remember current bank
- jmp ?bank ; and go exit through users
- ; physical bank select routine
-
-
- xofflist:
- db -1,-1,-1,-1,-1,-1,-1,-1 ; ctl-s clears to zero
- db -1,-1,-1,-1,-1,-1,-1,-1
-
-
-
- dseg ; following resides in banked memory
-
-
-
- ; Disk I/O interface routines
- ;
- ; SELDSK
- ; Select Disk Drive. Drive code in <C>.
- ; Invoke login procedure for drive
- ; if this is first select. Return
- ; address of disk parameter header
- ; in <HL>
- seldsk:
- mov a,c
- sta @adrv ; save drive select code
- mov l,c
- mvi h,0
- dad h ; create index from drive code
- lxi b,@dtbl
- dad b ; get pointer to dispatch table
- mov a,m
- inx h
- mov h,m
- mov l,a ; point at disk descriptor
- ora h
- rz ; if no entry in table, no disk
- mov a,e
- ani 1
- jrnz not$first$select ; examine login bit
- push h
- xchg ; put pointer in stack & <DE>
- lxi h,-2
- dad d
- mov a,m
- sta @RDRV ; get relative drive
- lxi h,-6
- dad d ; find LOGIN addr
- mov a,m
- inx h
- mov h,m
- mov l,a ; get address of LOGIN routine
- call ipchl ; call LOGIN
- pop h ; recover DPH pointer
- not$first$select:
- ret
-
- page
- ;
- ; HOME
- ; Home selected drive. Treated as SETTRK(0).
- home:
- lxi b,0 ; same as set track zero
-
-
- ;
- ; SETTRK
- ; Set Track. Saves track address from <BC>
- ; in @TRK for further operations.
- settrk:
- mov l,c
- mov h,b
- shld @trk
- ret
-
-
- ;
- ; SETSEC
- ; Set Sector. Saves sector number from <BC>
- ; in @sect for further operations.
- setsec:
- mov l,c
- mov h,b
- shld @sect
- ret
-
-
- ;
- ; SETDMA
- ; Set Disk Memory Address. Saves DMA address
- ; from <BC> in @DMA and sets @DBNK to @CBNK
- ; so that further disk operations take place
- ; in current bank.
- setdma:
- mov l,c
- mov h,b
- shld @dma
- lda @cbnk ; default DMA bank is current bank
- ; fall through to set DMA bank
-
- ;
- ; SETBNK
- ; Set Disk Memory Bank. Saves bank number
- ; in @DBNK for future disk data
- ; transfers.
- setbnk:
- sta @dbnk
- ret
-
- page
- ;
- ;
- ; SECTRN
- ; Sector Translate. Indexes skew table in <DE>
- ; with sector in <BC>. Returns physical sector
- ; in <HL>. If no skew table (<DE>=0) then
- ; returns physical=logical.
- sectrn:
- mov l,c
- mov h,b
- mov a,d
- ora e
- rz
- xchg
- dad b
- mov l,m
- mvi h,0
- ret
-
- page
- ;
- ; READ
- ; Read physical record from currently selected drive.
- ; Finds address of proper read routine from
- ; extended disk parameter header (XDPH).
- read:
- lhld @adrv
- mvi h,0
- dad h ; get drive code and double it
- lxi d,@dtbl
- dad d ; make address of table entry
- mov a,m
- inx h
- mov h,m
- mov l,a ; fetch table entry
- push h ; save address of table
- lxi d,-8
- dad d ; point to read routine address
- jr rw$common ; use common code
-
-
- ;
- ; WRITE
- ; Write physical sector from currently selected drive.
- ; Finds address of proper write routine from
- ; extended disk parameter header (XDPH).
- write:
- lhld @adrv
- mvi h,0
- dad h ; get drive code and double it
- lxi d,@dtbl
- dad d ; make address of table entry
- mov a,m
- inx h
- mov h,m
- mov l,a ; fetch table entry
- push h ; save address of table
- lxi d,-10
- dad d ; point to write routine address
-
- rw$common:
- mov a,m
- inx h
- mov h,m
- mov l,a ; get address of routine
- pop d ; recover address of table
- dcx d
- dcx d ; point to relative drive
- ldax d
- sta @rdrv ; get relative drive code and post it
- inx d
- inx d ; point to DPH again
- ipchl:
- pchl ; leap to driver
-
- page
- ;
- ; MULTIO
- ; Set multiple sector count. Saves passed count in
- ; @CNT
- multio:
- sta @cnt
- ret
-
- ;
- ; FLUSH
- ; BIOS deblocking buffer flush. Not implemented.
- flush:
- xra a
- ret ; return with no error
-
-
- ;
- ; error message components
- ;
- drive$msg: db cr,lf,bell,'BIOS Error on ',0
- track$msg: db ': T-',0
- sector$msg: db ', S-',0
-
-
- end