home *** CD-ROM | disk | FTP | other *** search
/ norge.freeshell.org (192.94.73.8) / 192.94.73.8.tar / 192.94.73.8 / pub / computers / cpm / alphatronic / DRIPAK.ZIP / CPM_3-0 / SOURCES / BIOSKRNL.ASM < prev    next >
Assembly Source File  |  1982-12-31  |  16KB  |  654 lines

  1.     title    'Root module of relocatable BIOS for CP/M 3.0'
  2.  
  3.     ; version 1.0 15 Sept 82
  4.  
  5. true    equ -1
  6. false    equ not true
  7.  
  8. banked    equ true
  9.     
  10.  
  11. ;          Copyright (C), 1982
  12. ;         Digital Research, Inc
  13. ;             P.O. Box 579
  14. ;        Pacific Grove, CA  93950
  15.  
  16.  
  17. ;   This is the invariant portion of the modular BIOS and is
  18. ;    distributed as source for informational purposes only.
  19. ;    All desired modifications should be performed by
  20. ;    adding or changing externally defined modules.
  21. ;    This allows producing "standard" I/O modules that
  22. ;    can be combined to support a particular system 
  23. ;    configuration.
  24.  
  25. cr    equ 13
  26. lf    equ 10
  27. bell    equ 7
  28. ctlQ    equ 'Q'-'@'
  29. ctlS    equ 'S'-'@'
  30.  
  31. ccp    equ 0100h    ; Console Command Processor gets loaded into the TPA
  32.  
  33.     cseg        ; GENCPM puts CSEG stuff in common memory
  34.  
  35.  
  36.     ; variables in system data page
  37.  
  38.     extrn @covec,@civec,@aovec,@aivec,@lovec ; I/O redirection vectors
  39.     extrn @mxtpa                ; addr of system entry point
  40.     extrn @bnkbf                ; 128 byte scratch buffer
  41.  
  42.     ; initialization
  43.  
  44.     extrn ?init            ; general initialization and signon
  45.     extrn ?ldccp,?rlccp        ; load & reload CCP for BOOT & WBOOT
  46.  
  47.     ; user defined character I/O routines
  48.  
  49.     extrn ?ci,?co,?cist,?cost    ; each take device in <B>
  50.     extrn ?cinit            ; (re)initialize device in <C>
  51.     extrn @ctbl            ; physical character device table
  52.  
  53.     ; disk communication data items
  54.  
  55.     extrn @dtbl            ; table of pointers to XDPHs
  56.     public @adrv,@rdrv,@trk,@sect    ; parameters for disk I/O
  57.     public @dma,@dbnk,@cnt        ;    ''       ''   ''  ''
  58.  
  59.     ; memory control
  60.  
  61.     public @cbnk            ; current bank
  62.     extrn ?xmove,?move        ; select move bank, and block move
  63.     extrn ?bank            ; select CPU bank
  64.  
  65.     ; clock support
  66.  
  67.     extrn ?time            ; signal time operation
  68.  
  69.     ; general utility routines
  70.  
  71.     public ?pmsg,?pdec    ; print message, print number from 0 to 65535
  72.     public ?pderr        ; print BIOS disk error message header
  73.  
  74.     maclib modebaud        ; define mode bits
  75.  
  76.  
  77.     ; External names for BIOS entry points
  78.  
  79.     public ?boot,?wboot,?const,?conin,?cono,?list,?auxo,?auxi
  80.     public ?home,?sldsk,?sttrk,?stsec,?stdma,?read,?write
  81.     public ?lists,?sctrn
  82.     public ?conos,?auxis,?auxos,?dvtbl,?devin,?drtbl
  83.     public ?mltio,?flush,?mov,?tim,?bnksl,?stbnk,?xmov
  84.  
  85.  
  86.     ; BIOS Jump vector.
  87.  
  88.         ; All BIOS routines are invoked by calling these
  89.         ;    entry points.
  90.  
  91. ?boot:    jmp boot    ; initial entry on cold start
  92. ?wboot:    jmp wboot    ; reentry on program exit, warm start
  93.  
  94. ?const:    jmp const    ; return console input status
  95. ?conin:    jmp conin    ; return console input character
  96. ?cono:    jmp conout    ; send console output character
  97. ?list:    jmp list    ; send list output character
  98. ?auxo:    jmp auxout    ; send auxilliary output character
  99. ?auxi:    jmp auxin    ; return auxilliary input character
  100.  
  101. ?home:    jmp home    ; set disks to logical home
  102. ?sldsk:    jmp seldsk    ; select disk drive, return disk parameter info
  103. ?sttrk:    jmp settrk    ; set disk track
  104. ?stsec:    jmp setsec    ; set disk sector
  105. ?stdma:    jmp setdma    ; set disk I/O memory address
  106. ?read:    jmp read    ; read physical block(s)
  107. ?write:    jmp write    ; write physical block(s)
  108.  
  109. ?lists:    jmp listst    ; return list device status
  110. ?sctrn:    jmp sectrn    ; translate logical to physical sector
  111.  
  112. ?conos:    jmp conost    ; return console output status
  113. ?auxis:    jmp auxist    ; return aux input status
  114. ?auxos:    jmp auxost    ; return aux output status
  115. ?dvtbl:    jmp devtbl    ; return address of device def table
  116. ?devin:    jmp ?cinit    ; change baud rate of device
  117.  
  118. ?drtbl:    jmp getdrv    ; return address of disk drive table
  119. ?mltio:    jmp multio    ; set multiple record count for disk I/O
  120. ?flush:    jmp flush    ; flush BIOS maintained disk caching
  121.  
  122. ?mov:    jmp ?move    ; block move memory to memory
  123. ?tim:    jmp ?time    ; Signal Time and Date operation
  124. ?bnksl:    jmp bnksel    ; select bank for code execution and default DMA
  125. ?stbnk:    jmp setbnk    ; select different bank for disk I/O DMA operations.
  126. ?xmov:    jmp ?xmove    ; set source and destination banks for one operation
  127.  
  128.     jmp 0        ; reserved for future expansion
  129.     jmp 0        ; reserved for future expansion
  130.     jmp 0        ; reserved for future expansion
  131.  
  132.  
  133.     ; BOOT
  134.     ;    Initial entry point for system startup.
  135.  
  136.     dseg    ; this part can be banked
  137.  
  138. boot:
  139.     lxi sp,boot$stack
  140.     mvi c,15    ; initialize all 16 character devices
  141. c$init$loop:
  142.     push b ! call ?cinit ! pop b
  143.     dcr c ! jp c$init$loop
  144.  
  145.     call ?init    ; perform any additional system initialization
  146.             ; and print signon message
  147.  
  148.     lxi b,16*256+0 ! lxi h,@dtbl    ; init all 16 logical disk drives
  149. d$init$loop:
  150.     push b        ; save remaining count and abs drive
  151.     mov e,m ! inx h ! mov d,m ! inx h    ; grab @drv entry
  152.     mov a,e ! ora d ! jz d$init$next    ; if null, no drive
  153.     push h                    ; save @drv pointer 
  154.     xchg                    ; XDPH address in <HL>
  155.     dcx h ! dcx h ! mov a,m ! sta @RDRV    ; get relative drive code
  156.     mov a,c ! sta @ADRV            ; get absolute drive code
  157.     dcx h                    ; point to init pointer
  158.     mov d,m ! dcx h ! mov e,m        ; get init pointer
  159.     xchg ! call ipchl            ; call init routine
  160.     pop h                    ; recover @drv pointer
  161. d$init$next:
  162.     pop b                    ; recover counter and drive #
  163.     inr c ! dcr b ! jnz d$init$loop        ; and loop for each drive
  164.     jmp boot$1
  165.  
  166.     cseg    ; following in resident memory
  167.  
  168. boot$1:
  169.     call set$jumps
  170.     call ?ldccp                ; fetch CCP for first time
  171.     jmp ccp
  172.  
  173.  
  174.     ; WBOOT
  175.     ;    Entry for system restarts.
  176.  
  177. wboot:
  178.     lxi sp,boot$stack
  179.     call set$jumps        ; initialize page zero
  180.     call ?rlccp        ; reload CCP
  181.     jmp ccp            ; then reset jmp vectors and exit to ccp
  182.  
  183.  
  184. set$jumps:
  185.  
  186.   if banked
  187.     mvi a,1 ! call ?bnksl
  188.   endif
  189.  
  190.     mvi a,JMP
  191.     sta 0 ! sta 5        ; set up jumps in page zero
  192.     lxi h,?wboot ! shld 1    ; BIOS warm start entry
  193.     lhld @MXTPA ! shld 6    ; BDOS system call entry
  194.     ret
  195.  
  196.  
  197.         ds 64
  198. boot$stack    equ $
  199.  
  200.  
  201.     ; DEVTBL
  202.     ;    Return address of character device table
  203.  
  204. devtbl:
  205.     lxi h,@ctbl ! ret
  206.  
  207.  
  208.     ; GETDRV
  209.     ;    Return address of drive table
  210.  
  211. getdrv:
  212.     lxi h,@dtbl ! ret
  213.  
  214.  
  215.  
  216.     ; CONOUT
  217.     ;    Console Output.  Send character in <C>
  218.     ;            to all selected devices
  219.  
  220. conout:    
  221.  
  222.     lhld @covec    ; fetch console output bit vector
  223.     jmp out$scan
  224.  
  225.  
  226.     ; AUXOUT
  227.     ;    Auxiliary Output. Send character in <C>
  228.     ;            to all selected devices
  229.  
  230. auxout:
  231.     lhld @aovec    ; fetch aux output bit vector
  232.     jmp out$scan
  233.  
  234.  
  235.     ; LIST
  236.     ;    List Output.  Send character in <C>
  237.     ;            to all selected devices.
  238.  
  239. list:
  240.     lhld @lovec    ; fetch list output bit vector
  241.  
  242. out$scan:
  243.     mvi b,0        ; start with device 0
  244. co$next:
  245.     dad h        ; shift out next bit
  246.     jnc not$out$device
  247.     push h        ; save the vector
  248.     push b        ; save the count and character
  249. not$out$ready:
  250.     call coster ! ora a ! jz not$out$ready
  251.     pop b ! push b    ; restore and resave the character and device
  252.     call ?co    ; if device selected, print it
  253.     pop b        ; recover count and character
  254.     pop h        ; recover the rest of the vector
  255. not$out$device:
  256.     inr b        ; next device number
  257.     mov a,h ! ora l    ; see if any devices left
  258.     jnz co$next    ; and go find them...
  259.     ret
  260.  
  261.  
  262.     ; CONOST
  263.     ;    Console Output Status.  Return true if
  264.     ;        all selected console output devices
  265.     ;        are ready.
  266.  
  267. conost:
  268.     lhld @covec    ; get console output bit vector
  269.     jmp ost$scan
  270.  
  271.  
  272.     ; AUXOST
  273.     ;    Auxiliary Output Status.  Return true if
  274.     ;        all selected auxiliary output devices
  275.     ;        are ready.
  276.  
  277. auxost:
  278.     lhld @aovec    ; get aux output bit vector
  279.     jmp ost$scan
  280.  
  281.  
  282.     ; LISTST
  283.     ;    List Output Status.  Return true if
  284.     ;        all selected list output devices
  285.     ;        are ready.
  286.  
  287. listst:
  288.     lhld @lovec    ; get list output bit vector
  289.  
  290. ost$scan:
  291.     mvi b,0        ; start with device 0
  292. cos$next:
  293.     dad h        ; check next bit
  294.     push h        ; save the vector
  295.     push b        ; save the count
  296.     mvi a,0FFh    ; assume device ready
  297.     cc coster    ; check status for this device
  298.     pop b        ; recover count
  299.     pop h        ; recover bit vector
  300.     ora a        ; see if device ready
  301.     rz        ; if any not ready, return false
  302.     inr b        ; drop device number
  303.     mov a,h ! ora l    ; see if any more selected devices
  304.     jnz cos$next
  305.     ori 0FFh    ; all selected were ready, return true
  306.     ret
  307.  
  308. coster:        ; check for output device ready, including optional
  309.         ;    xon/xoff support
  310.     mov l,b ! mvi h,0    ; make device code 16 bits
  311.     push h            ; save it in stack
  312.     dad h ! dad h ! dad h    ; create offset into device characteristics tbl
  313.     lxi d,@ctbl+6 ! dad d    ; make address of mode byte
  314.     mov a,m ! ani mb$xonxoff
  315.     pop h            ; recover console number in <HL>
  316.     jz ?cost        ; not a xon device, go get output status direct
  317.     lxi d,xofflist ! dad d    ; make pointer to proper xon/xoff flag
  318.     call cist1        ; see if this keyboard has character
  319.     mov a,m ! cnz ci1    ; get flag or read key if any
  320.     cpi ctlq ! jnz not$q    ; if its a ctl-Q,
  321.     mvi a,0FFh         ;    set the flag ready
  322. not$q:
  323.     cpi ctls ! jnz not$s    ; if its a ctl-S,
  324.     mvi a,00h        ;    clear the flag
  325. not$s:
  326.     mov m,a            ; save the flag
  327.     call cost1        ; get the actual output status,
  328.     ana m            ; and mask with ctl-Q/ctl-S flag
  329.     ret            ; return this as the status
  330.  
  331. cist1:            ; get input status with <BC> and <HL> saved
  332.     push b ! push h 
  333.     call ?cist
  334.     pop h ! pop b
  335.     ora a
  336.     ret
  337.  
  338. cost1:            ; get output status, saving <BC> & <HL>
  339.     push b ! push h
  340.     call ?cost
  341.     pop h ! pop b
  342.     ora a
  343.     ret
  344.  
  345. ci1:            ; get input, saving <BC> & <HL>
  346.     push b ! push h
  347.     call ?ci
  348.     pop h ! pop b
  349.     ret
  350.  
  351.  
  352.     ; CONST
  353.     ;    Console Input Status.  Return true if
  354.     ;        any selected console input device
  355.     ;        has an available character.
  356.  
  357. const:
  358.     lhld @civec    ; get console input bit vector
  359.     jmp ist$scan
  360.  
  361.  
  362.     ; AUXIST
  363.     ;    Auxiliary Input Status.  Return true if
  364.     ;        any selected auxiliary input device
  365.     ;        has an available character.
  366.  
  367. auxist:
  368.     lhld @aivec    ; get aux input bit vector
  369.  
  370. ist$scan:
  371.     mvi b,0        ; start with device 0
  372. cis$next:
  373.     dad h        ; check next bit
  374.     mvi a,0        ; assume device not ready
  375.     cc cist1    ; check status for this device
  376.     ora a ! rnz    ; if any ready, return true
  377.     inr b        ; drop device number
  378.     mov a,h ! ora l    ; see if any more selected devices
  379.     jnz cis$next
  380.     xra a        ; all selected were not ready, return false
  381.     ret
  382.  
  383.  
  384.     ; CONIN
  385.     ;    Console Input.  Return character from first
  386.     ;        ready console input device.
  387.  
  388. conin:
  389.     lhld @civec
  390.     jmp in$scan
  391.  
  392.  
  393.     ; AUXIN
  394.     ;    Auxiliary Input.  Return character from first
  395.     ;        ready auxiliary input device.
  396.  
  397. auxin:
  398.     lhld @aivec
  399.  
  400. in$scan:
  401.     push h        ; save bit vector
  402.     mvi b,0
  403. ci$next:
  404.     dad h        ; shift out next bit
  405.     mvi a,0        ; insure zero a  (nonexistant device not ready).
  406.     cc cist1    ; see if the device has a character
  407.     ora a
  408.     jnz ci$rdy    ; this device has a character
  409.     inr b        ; else, next device
  410.     mov a,h ! ora l    ; see if any more devices
  411.     jnz ci$next    ; go look at them
  412.     pop h        ; recover bit vector
  413.     jmp in$scan    ; loop til we find a character
  414.  
  415. ci$rdy:
  416.     pop h        ; discard extra stack
  417.     jmp ?ci
  418.  
  419.  
  420. ;    Utility Subroutines
  421.  
  422.  
  423. ipchl:        ; vectored CALL point
  424.     pchl
  425.  
  426.  
  427. ?pmsg:        ; print message @<HL> up to a null
  428.         ; saves <BC> & <DE>
  429.     push b
  430.     push d
  431. pmsg$loop:
  432.     mov a,m ! ora a ! jz pmsg$exit
  433.     mov c,a ! push h
  434.     call ?cono ! pop h
  435.     inx h ! jmp pmsg$loop
  436. pmsg$exit:
  437.     pop d
  438.     pop b
  439.     ret
  440.  
  441. ?pdec:        ; print binary number 0-65535 from <HL>
  442.     lxi b,table10! lxi d,-10000
  443. next:
  444.     mvi a,'0'-1
  445. pdecl:
  446.     push h! inr a! dad d! jnc stoploop
  447.     inx sp! inx sp! jmp pdecl
  448. stoploop:
  449.     push d! push b
  450.     mov c,a! call ?cono
  451.     pop b! pop d
  452. nextdigit:
  453.     pop h
  454.     ldax b! mov e,a! inx b
  455.     ldax b! mov d,a! inx b
  456.     mov a,e! ora d! jnz next
  457.     ret
  458.  
  459. table10:
  460.     dw    -1000,-100,-10,-1,0
  461.  
  462. ?pderr:
  463.     lxi h,drive$msg ! call ?pmsg            ; error header
  464.     lda @adrv ! adi 'A' ! mov c,a ! call ?cono    ; drive code
  465.     lxi h,track$msg ! call ?pmsg            ; track header
  466.     lhld @trk ! call ?pdec                ; track number
  467.     lxi h,sector$msg ! call ?pmsg            ; sector header
  468.     lhld @sect ! call ?pdec                ; sector number
  469.     ret
  470.  
  471.  
  472.     ; BNKSEL
  473.     ;    Bank Select.  Select CPU bank for further execution.
  474.  
  475. bnksel:
  476.     sta @cbnk             ; remember current bank
  477.     jmp ?bank            ; and go exit through users
  478.                     ; physical bank select routine
  479.  
  480.  
  481. xofflist    db    -1,-1,-1,-1,-1,-1,-1,-1        ; ctl-s clears to zero
  482.         db    -1,-1,-1,-1,-1,-1,-1,-1
  483.  
  484.  
  485.  
  486.     dseg    ; following resides in banked memory
  487.  
  488.  
  489.  
  490. ;    Disk I/O interface routines
  491.  
  492.  
  493.     ; SELDSK
  494.     ;    Select Disk Drive.  Drive code in <C>.
  495.     ;        Invoke login procedure for drive
  496.     ;        if this is first select.  Return
  497.     ;        address of disk parameter header
  498.     ;        in <HL>
  499.  
  500. seldsk:
  501.     mov a,c ! sta @adrv            ; save drive select code
  502.     mov l,c ! mvi h,0 ! dad h        ; create index from drive code
  503.     lxi b,@dtbl ! dad b            ; get pointer to dispatch table
  504.     mov a,m ! inx h ! mov h,m ! mov l,a    ; point at disk descriptor
  505.     ora h ! rz                 ; if no entry in table, no disk
  506.     mov a,e ! ani 1 ! jnz not$first$select    ; examine login bit
  507.     push h ! xchg                ; put pointer in stack & <DE>
  508.     lxi h,-2 ! dad d ! mov a,m ! sta @RDRV    ; get relative drive
  509.     lxi h,-6 ! dad d            ; find LOGIN addr
  510.     mov a,m ! inx h ! mov h,m ! mov l,a    ; get address of LOGIN routine
  511.     call ipchl                ; call LOGIN
  512.     pop h                    ; recover DPH pointer
  513. not$first$select:
  514.     ret
  515.  
  516.  
  517.     ; HOME
  518.     ;    Home selected drive.  Treated as SETTRK(0).
  519.  
  520. home:
  521.     lxi b,0        ; same as set track zero
  522.  
  523.  
  524.     ; SETTRK
  525.     ;    Set Track. Saves track address from <BC> 
  526.     ;        in @TRK for further operations.
  527.  
  528. settrk:
  529.     mov l,c ! mov h,b
  530.     shld @trk
  531.     ret
  532.  
  533.  
  534.     ; SETSEC
  535.     ;    Set Sector.  Saves sector number from <BC>
  536.     ;        in @sect for further operations.
  537.  
  538. setsec:
  539.     mov l,c ! mov h,b
  540.     shld @sect
  541.     ret
  542.  
  543.  
  544.     ; SETDMA
  545.     ;    Set Disk Memory Address.  Saves DMA address
  546.     ;        from <BC> in @DMA and sets @DBNK to @CBNK
  547.     ;        so that further disk operations take place
  548.     ;        in current bank.
  549.  
  550. setdma:
  551.     mov l,c ! mov h,b
  552.     shld @dma
  553.  
  554.     lda @cbnk    ; default DMA bank is current bank
  555.             ; fall through to set DMA bank
  556.  
  557.     ; SETBNK
  558.     ;    Set Disk Memory Bank.  Saves bank number
  559.     ;        in @DBNK for future disk data
  560.     ;        transfers.
  561.  
  562. setbnk:
  563.     sta @dbnk
  564.     ret
  565.  
  566.  
  567.     ; SECTRN
  568.     ;    Sector Translate.  Indexes skew table in <DE>
  569.     ;        with sector in <BC>.  Returns physical sector
  570.     ;        in <HL>.  If no skew table (<DE>=0) then
  571.     ;        returns physical=logical.
  572.  
  573. sectrn:
  574.     mov l,c ! mov h,b
  575.     mov a,d ! ora e ! rz
  576.     xchg ! dad b ! mov l,m ! mvi h,0
  577.     ret
  578.  
  579.  
  580.     ; READ
  581.     ;    Read physical record from currently selected drive.
  582.     ;        Finds address of proper read routine from
  583.     ;        extended disk parameter header (XDPH).
  584.  
  585. read:
  586.     lhld @adrv ! mvi h,0 ! dad h    ; get drive code and double it
  587.     lxi d,@dtbl ! dad d        ; make address of table entry
  588.     mov a,m ! inx h ! mov h,m ! mov l,a    ; fetch table entry
  589.     push h                ; save address of table
  590.     lxi d,-8 ! dad d        ; point to read routine address
  591.     jmp rw$common            ; use common code
  592.  
  593.  
  594.     ; WRITE
  595.     ;    Write physical sector from currently selected drive.
  596.     ;        Finds address of proper write routine from
  597.     ;        extended disk parameter header (XDPH).
  598.  
  599. write:
  600.     lhld @adrv ! mvi h,0 ! dad h    ; get drive code and double it
  601.     lxi d,@dtbl ! dad d        ; make address of table entry
  602.     mov a,m ! inx h ! mov h,m ! mov l,a    ; fetch table entry
  603.     push h                ; save address of table
  604.     lxi d,-10 ! dad d        ; point to write routine address
  605.  
  606. rw$common:
  607.     mov a,m ! inx h ! mov h,m ! mov l,a    ; get address of routine
  608.     pop d                ; recover address of table
  609.     dcx d ! dcx d            ; point to relative drive
  610.     ldax d ! sta @rdrv        ; get relative drive code and post it
  611.     inx d ! inx d            ; point to DPH again
  612.     pchl                ; leap to driver
  613.  
  614.  
  615.     ; MULTIO
  616.     ;    Set multiple sector count. Saves passed count in
  617.     ;        @CNT
  618.  
  619. multio:
  620.     sta @cnt ! ret
  621.  
  622.  
  623.     ; FLUSH
  624.     ;    BIOS deblocking buffer flush.  Not implemented.
  625.  
  626. flush:
  627.     xra a ! ret        ; return with no error
  628.  
  629.  
  630.  
  631.     ; error message components
  632. drive$msg    db    cr,lf,bell,'BIOS Error on ',0
  633. track$msg    db    ': T-',0
  634. sector$msg    db    ', S-',0
  635.  
  636.  
  637.     ; disk communication data items
  638.  
  639. @adrv    ds    1        ; currently selected disk drive
  640. @rdrv    ds    1        ; controller relative disk drive
  641. @trk    ds    2        ; current track number
  642. @sect    ds    2        ; current sector number
  643. @dma    ds    2        ; current DMA address
  644. @cnt    db    0        ; record count for multisector transfer
  645. @dbnk    db    0        ; bank for DMA operations
  646.  
  647.  
  648.     cseg    ; common memory
  649.  
  650. @cbnk    db    0        ; bank for processor operations
  651.  
  652.  
  653.     end
  654.