]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blobdiff - cbios/bioskrnl.180
divde and round
[z180-stamp-cpm3.git] / cbios / bioskrnl.180
index 93d556da10407dad903d4852a74558ac6f78f1dd..2a00c90aa87d08ea61799d3f18a5ebbd10cec7e3 100644 (file)
@@ -26,10 +26,10 @@ bell        equ     7
 ctlQ   equ     'Q'-'@'\r
 ctlS   equ     'S'-'@'\r
 \r
-ccp    equ     0100h                   ; Console Command Processor gets loaded\r
-                                       ; into the TPA\r
+ccp    equ     0100h           ; Console Command Processor gets loaded\r
+                               ; into the TPA\r
 \r
-       cseg                            ; GENCPM puts CSEG stuff in common memory\r
+       cseg                    ; GENCPM puts CSEG stuff in common memory\r
 \r
 \r
     ; variables in system data page\r
@@ -40,7 +40,7 @@ ccp   equ     0100h                   ; Console Command Processor gets loaded
 \r
     ; initialization\r
 \r
-       extrn hwinit,?init                      ; general initialization and signon\r
+       extrn hwinit,?init              ; general initialization and signon\r
        extrn ?ldccp,?rlccp             ; load & reload CCP for BOOT & WBOOT\r
 \r
     ; user defined character I/O routines\r
@@ -67,10 +67,13 @@ ccp equ     0100h                   ; Console Command Processor gets loaded
 \r
     ; general utility routines\r
 \r
-       public ?pmsg,?pdec      ; print message, print number from 0 to 65535\r
-       public ?pderr           ; print BIOS disk error message header\r
-       public pmsg.in          ; print message inline\r
-       public phex4,phex2      ; print 4 digit hex (HL), or 2 digit hex (A)\r
+       public ?pmsg                    ; print message\r
+       public pr.dec,pr.decl           ; print 16 or 32 bit decimal number\r
+       public ?pderr                   ; print BIOS disk error message header\r
+       public pr.inln,pr.crlf          ; print message inline\r
+       public phex4,phex2              ; print 4 digit hex (HL), or 2 digit hex (A)\r
+\r
+       extrn div32_16                  ; divide 32 bit by 16 bit number\r
 \r
        include modebaud.inc            ; define mode bits\r
 \r
@@ -88,45 +91,45 @@ ccp equ     0100h                   ; Console Command Processor gets loaded
 \r
     ; BIOS Jump vector.\r
 \r
-               ; All BIOS routines are invoked by calling these\r
-               ;       entry points.\r
-\r
-?boot: jp      boot    ; initial entry on cold start\r
-?wboot:        jp      wboot   ; reentry on program exit, warm start\r
-\r
-?const:        jp      const   ; return console input status\r
-?conin:        jp      conin   ; return console input character\r
-?cono: jp      conout  ; send console output character\r
-?list: jp      list    ; send list output character\r
-?auxo: jp      auxout  ; send auxiliary output character\r
-?auxi: jp      auxin   ; return auxiliary input character\r
-\r
-?home: jp      home    ; set disks to logical home\r
-?sldsk:        jp      seldsk  ; select disk drive, return disk parameter info\r
-?sttrk:        jp      settrk  ; set disk track\r
-?stsec:        jp      setsec  ; set disk sector\r
-?stdma:        jp      setdma  ; set disk I/O memory address\r
-?read: jp      read    ; read physical block(s)\r
-?write:        jp      write   ; write physical block(s)\r
-\r
-?lists:        jp      listst  ; return list device status\r
-?sctrn:        jp      sectrn  ; translate logical to physical sector\r
-\r
-?conos:        jp      conost  ; return console output status\r
-?auxis:        jp      auxist  ; return aux input status\r
-?auxos:        jp      auxost  ; return aux output status\r
-?dvtbl:        jp      devtbl  ; return address of device def table\r
-?devin:        jp      ?cinit  ; change baud rate of device\r
-\r
-?drtbl:        jp      getdrv  ; return address of disk drive table\r
-?mltio:        jp      multio  ; set multiple record count for disk I/O\r
-?flush:        jp      flush   ; flush BIOS maintained disk caching\r
-\r
-?mov:  jp      ?move   ; block move memory to memory\r
-?tim:  jp      ?time   ; Signal Time and Date operation\r
-?bnksl:        jp      bnksel  ; select bank for code execution and default DMA\r
-?stbnk:        jp      setbnk  ; select different bank for disk I/O DMA operations\r
-?xmov: jp      ?xmove  ; set source and destination banks for one operation\r
+       ; All BIOS routines are invoked by calling these\r
+       ;       entry points.\r
+\r
+?boot: jp      boot            ; initial entry on cold start\r
+?wboot:        jp      wboot           ; reentry on program exit, warm start\r
+\r
+?const:        jp      const           ; return console input status\r
+?conin:        jp      conin           ; return console input character\r
+?cono: jp      conout          ; send console output character\r
+?list: jp      list            ; send list output character\r
+?auxo: jp      auxout          ; send auxiliary output character\r
+?auxi: jp      auxin           ; return auxiliary input character\r
+\r
+?home: jp      home            ; set disks to logical home\r
+?sldsk:        jp      seldsk          ; select disk drive, return disk parameter info\r
+?sttrk:        jp      settrk          ; set disk track\r
+?stsec:        jp      setsec          ; set disk sector\r
+?stdma:        jp      setdma          ; set disk I/O memory address\r
+?read: jp      read            ; read physical block(s)\r
+?write:        jp      write           ; write physical block(s)\r
+\r
+?lists:        jp      listst          ; return list device status\r
+?sctrn:        jp      sectrn          ; translate logical to physical sector\r
+\r
+?conos:        jp      conost          ; return console output status\r
+?auxis:        jp      auxist          ; return aux input status\r
+?auxos:        jp      auxost          ; return aux output status\r
+?dvtbl:        jp      devtbl          ; return address of device def table\r
+?devin:        jp      ?cinit          ; change baud rate of device\r
+\r
+?drtbl:        jp      getdrv          ; return address of disk drive table\r
+?mltio:        jp      multio          ; set multiple record count for disk I/O\r
+?flush:        jp      flush           ; flush BIOS maintained disk caching\r
+\r
+?mov:  jp      ?move           ; block move memory to memory\r
+?tim:  jp      ?time           ; Signal Time and Date operation\r
+?bnksl:        jp      bnksel          ; select bank for code execution and default DMA\r
+?stbnk:        jp      setbnk          ; select different bank for disk I/O DMA operations\r
+?xmov: jp      ?xmove          ; set source and destination banks for one operation\r
 \r
        jp      0               ; reserved for future expansion\r
        jp      0               ; reserved for future expansion\r
@@ -136,69 +139,69 @@ ccp       equ     0100h                   ; Console Command Processor gets loaded
        ; BOOT\r
        ;       Initial entry point for system startup.\r
 \r
-       dseg    ; this part can be banked\r
+       dseg                    ; this part can be banked\r
 \r
 boot:\r
        ld      sp,bs$stack\r
 \r
-       call    hwinit  ; first time hardware initialisation\r
+       call    hwinit          ; first time hardware initialisation\r
 \r
-       ld      c,15    ; initialize all 16 character devices\r
+       ld      bc,16*256 + 0   ; initialize all 16 character devices\r
 c$init$loop:\r
        push    bc\r
        call    ?cinit\r
        pop     bc\r
-       dec     c\r
-       jp      p,c$init$loop\r
+       inc     c\r
+       djnz    c$init$loop\r
 \r
-       call    ?init   ; perform any additional system initialization\r
-                       ; and print signon message\r
+       call    ?init           ; perform any additional system initialization\r
+                               ; and print signon message\r
 \r
        ld      bc,16*256+0\r
-       ld      hl,@dtbl                ; init all 16 logical disk drives\r
+       ld      hl,@dtbl        ; init all 16 logical disk drives\r
 d$init$loop:\r
-       push    bc                      ; save remaining count and abs drive\r
+       push    bc              ; save remaining count and abs drive\r
        ld      e,(hl)\r
        inc     hl\r
        ld      d,(hl)\r
-       inc     hl                      ; grab @drv entry\r
+       inc     hl              ; grab @drv entry\r
        ld      a,e\r
        or      d\r
-       jr      z,d$init$next           ; if null, no drive\r
-       push    hl                      ; save @drv pointer\r
+       jr      z,d$init$next   ; if null, no drive\r
+       push    hl              ; save @drv pointer\r
    if 0\r
-       ex      de,hl                   ; XDPH address in <HL>\r
+       ex      de,hl           ; XDPH address in <HL>\r
        dec     hl\r
        dec     hl\r
-       ld      b,(hl)                  ; get relative drive code\r
-       ld      (@ADRV),bc              ; save absolute and relative drive code\r
-       dec     hl                      ; point to init pointer\r
+       ld      b,(hl)          ; get relative drive code\r
+       ld      (@ADRV),bc      ; save absolute and relative drive code\r
+       dec     hl              ; point to init pointer\r
        ld      d,(hl)\r
        dec     hl\r
-       ld      e,(hl)                  ; get init pointer\r
+       ld      e,(hl)          ; get init pointer\r
        ex      de,hl\r
-       call    ipchl                   ; call init routine\r
+       call    ipchl           ; call init routine\r
    else\r
        push    de\r
        pop     ix\r
        ld      b,(ix-2)\r
-       ld      (@ADRV),bc              ; save absolute and relative drive code\r
+       ld      (@ADRV),bc      ; save absolute and relative drive code\r
        ld      l,(ix-4)\r
-       ld      h,(ix-3)                ; get init pointer\r
-       call    ipchl                   ; call init routine\r
+       ld      h,(ix-3)        ; get init pointer\r
+       call    ipchl           ; call init routine\r
    endif\r
-       pop     hl                      ; recover @drv pointer\r
+       pop     hl              ; recover @drv pointer\r
 d$init$next:\r
-       pop     bc                      ; recover counter and drive #\r
+       pop     bc              ; recover counter and drive #\r
        inc     c\r
-       djnz    d$init$loop             ; and loop for each drive\r
+       djnz    d$init$loop     ; and loop for each drive\r
        jp      boot$1\r
 \r
        cseg    ; following in resident memory\r
 \r
 boot$1:\r
        call    set$jumps\r
-       call    ?ldccp                  ; fetch CCP for first time\r
+       call    ?ldccp          ; fetch CCP for first time\r
        jp      ccp\r
 \r
 \r
@@ -207,9 +210,9 @@ boot$1:
 \r
 wboot:\r
        ld      sp,bs$stack\r
-       call    set$jumps               ; initialize page zero\r
-       call    ?rlccp                  ; reload CCP\r
-       jp      ccp                     ; then reset jmp vectors and exit to ccp\r
+       call    set$jumps       ; initialize page zero\r
+       call    ?rlccp          ; reload CCP\r
+       jp      ccp             ; then reset jmp vectors and exit to ccp\r
 \r
 \r
 set$jumps:\r
@@ -288,14 +291,14 @@ not$out$ready:
        or      a\r
        jp      z,not$out$ready\r
        pop     bc\r
-       push    bc      ; restore and resave the character and device\r
-       call    ?co     ; if device selected, print it\r
+       push    bc              ; restore and resave the character and device\r
+       call    ?co             ; if device selected, print it\r
        pop     bc              ; recover count and character\r
        pop     hl              ; recover the rest of the vector\r
 not$out$device:\r
        inc     b               ; next device number\r
        ld      a,h\r
-       or      l       ; see if any devices left\r
+       or      l               ; see if any devices left\r
        jr      nz,co$next      ; and go find them...\r
        ret\r
 \r
@@ -334,7 +337,7 @@ cos$next:
        add     hl,hl           ; check next bit\r
        push    hl              ; save the vector\r
        push    bc              ; save the count\r
-       ld      a,0FFh  ; assume device ready\r
+       ld      a,0FFh          ; assume device ready\r
        call    c,coster        ; check status for this device\r
        pop     bc              ; recover count\r
        pop     hl              ; recover bit vector\r
@@ -342,30 +345,31 @@ cos$next:
        ret     z                       ; if any not ready, return false\r
        inc     b               ; drop device number\r
        ld      a,h\r
-       or      l       ; see if any more selected devices\r
+       or      l               ; see if any more selected devices\r
        jr      nz,cos$next\r
-       or      0FFh    ; all selected were ready, return true\r
+       or      0FFh            ; all selected were ready, return true\r
        ret\r
 \r
-coster:                ; check for output device ready, including optional\r
-               ;       xon/xoff support\r
+       ; check for output device ready, including optional\r
+       ;       xon/xoff support\r
+coster:\r
        ld      l,b\r
-       ld      h,0     ; make device code 16 bits\r
-       push    hl                      ; save it in stack\r
+       ld      h,0             ; make device code 16 bits\r
+       push    hl              ; save it in stack\r
        add     hl,hl\r
        add     hl,hl\r
-       add     hl,hl   ; create offset into device characteristics tbl\r
+       add     hl,hl           ; create offset into device characteristics tbl\r
        ld      de,@ctbl+6\r
-       add     hl,de   ; make address of mode byte\r
+       add     hl,de           ; make address of mode byte\r
        ld      a,(hl)\r
        and     mb$xon$xoff\r
-       pop     hl                      ; recover console number in <HL>\r
+       pop     hl              ; recover console number in <HL>\r
        jp      z,?cost         ; not a xon device, go get output status direct\r
        ld      de,xofflist\r
-       add     hl,de   ; make pointer to proper xon/xoff flag\r
+       add     hl,de           ; make pointer to proper xon/xoff flag\r
        call    cist1           ; see if this keyboard has character\r
        ld      a,(hl)\r
-       call    nz,ci1  ; get flag or read key if any\r
+       call    nz,ci1          ; get flag or read key if any\r
        cp      ctlq\r
        jr      nz,not$q        ; if its a ctl-Q,\r
        ld      a,0FFh          ;       set the flag ready\r
@@ -374,12 +378,12 @@ not$q:
        jr      nz,not$s        ; if its a ctl-S,\r
        ld      a,00h           ;       clear the flag\r
 not$s:\r
-       ld      (hl),a                  ; save the flag\r
+       ld      (hl),a          ; save the flag\r
        call    cost1           ; get the actual output status,\r
-       and     (hl)                    ; and mask with ctl-Q/ctl-S flag\r
+       and     (hl)            ; and mask with ctl-Q/ctl-S flag\r
        ret                     ; return this as the status\r
 \r
-cist1:                 ; get input status with <BC> and <HL> saved\r
+cist1:                         ; get input status with <BC> and <HL> saved\r
        push    bc\r
        push    hl\r
        call    ?cist\r
@@ -388,7 +392,7 @@ cist1:                      ; get input status with <BC> and <HL> saved
        or      a\r
        ret\r
 \r
-cost1:                 ; get output status, saving <BC> & <HL>\r
+cost1:                         ; get output status, saving <BC> & <HL>\r
        push    bc\r
        push    hl\r
        call    ?cost\r
@@ -397,7 +401,7 @@ cost1:                      ; get output status, saving <BC> & <HL>
        or      a\r
        ret\r
 \r
-ci1:                   ; get input, saving <BC> & <HL>\r
+ci1:                           ; get input, saving <BC> & <HL>\r
        push    bc\r
        push    hl\r
        call    ?ci\r
@@ -434,7 +438,7 @@ cis$next:
        ret     nz              ; if any ready, return true\r
        inc     b               ; next device number\r
        ld      a,h\r
-       or      l       ; see if any more selected devices\r
+       or      l               ; see if any more selected devices\r
        jr      nz,cis$next\r
        xor     a               ; all selected were not ready, return false\r
        ret\r
@@ -511,7 +515,7 @@ pmsg$exit:
 ; print message inline up to a null\r
 ; saves all registers\r
 \r
-pmsg.in:\r
+pr.inln:\r
        ex      (sp),hl\r
        push    af\r
        call    ?pmsg\r
@@ -519,6 +523,15 @@ pmsg.in:
        ex      (sp),hl\r
        ret\r
 \r
+;-------------------------------------------------------------------------------\r
+; print <CR><LF>\r
+; saves all registers\r
+\r
+pr.crlf:\r
+       call    pr.inln\r
+       db      13,10,0\r
+       ret\r
+\r
 ;-------------------------------------------------------------------------------\r
 ; print hl as a 4 digit hexadecimal number\r
 ; saves all registers\r
@@ -562,59 +575,101 @@ prd_1:
        pop     hl\r
        ret\r
 \r
+\r
+;-------------------------------------------------------------------------------\r
+; print decimal 16 bit number from HL\r
+;\r
+;      HL: unsigned binary number to print\r
+;       C: minimum print field width\r
+;          number is prined right-aligned\r
+;       B: pad character, typically ' ' or '0'\r
+\r
+pr.dec:\r
+       push    de\r
+       ld      de,0\r
+       call    pr.decl\r
+       pop     de\r
+       ret\r
+\r
 ;-------------------------------------------------------------------------------\r
+; print decimal 32 bit number from DEHL\r
+;\r
+;      DEHL: unsigned binary number to print\r
+;         C: minimum print field width\r
+;            number is prined right-aligned\r
+;         B: pad character, typically ' ' or '0'\r
+\r
+pr.decl:\r
+       push    bc              ;save width and fillchar\r
+       push    bc\r
+       exx                     ;(alt)\r
+       ex      (sp),hl         ;save hl', get width and fill\r
+       push    de              ;save de'\r
 \r
-?pdec:         ; print binary number 0-65535 from <HL>\r
-       ld      bc,table10\r
-       ld      de,-10000\r
-next:\r
-       ld      a,'0'-1\r
-pdecl:\r
-       push    hl\r
-       inc     a\r
-       add     hl,de\r
-       jp      nc,stoploop\r
+       xor     a\r
+       ld      d,a             ;clear counter\r
+       ld      e,a\r
+       push    af              ; string terminator\r
        inc     sp\r
+\r
+prd_divloop:                   ;do\r
+       exx                     ;    (main)\r
+       ld      bc,10           ;\r
+       call    div32_16        ;    get a digit\r
+       ld      a,c             ;\r
+       add     a,'0'           ;    make it printable\r
+       push    af              ;\r
+\r
+       ld      a,h             ;\r
+       or      l               ;\r
+       or      d               ;\r
+       or      e               ;\r
+       exx                     ;    (alt)\r
+       inc     sp              ;\r
+       inc     de              ;\r
+       jr      nz,prd_divloop  ;\r
+\r
+prd_filloop:                   ;h=filler, l=field width\r
+       ld      a,e\r
+       cp      l\r
+       jr      nc,prd_out\r
+       push    hl\r
        inc     sp\r
-       jp      pdecl\r
-stoploop:\r
-       push    de\r
-       push    bc\r
-       ld      c,a\r
-       call    ?cono\r
-       pop     bc\r
+       inc     de\r
+       jr      prd_filloop\r
+prd_out:\r
+       ld      hl,0\r
+       add     hl,sp           ;ptr to beginning of number string (hl==0 here)\r
+       call    ?pmsg\r
+       ex      de,hl\r
+       add     hl,sp\r
+       ld      sp,hl\r
+       inc     sp              ;remove string terminator\r
        pop     de\r
-nextdigit:\r
        pop     hl\r
-       ld      a,(bc)\r
-       ld      e,a\r
-       inc     bc\r
-       ld      a,(bc)\r
-       ld      d,a\r
-       inc     bc\r
-       ld      a,e\r
-       or      d\r
-       jp      nz,next\r
+       exx                     ;(main)\r
+       pop     bc\r
        ret\r
 \r
-table10:\r
-       dw      -1000,-100,-10,-1,0\r
 \r
+;-------------------------------------------------------------------------------\r
+;\r
 ?pderr:\r
        ld      hl,drive$msg\r
-       call    ?pmsg                   ; error header\r
+       call    ?pmsg           ; error header\r
        ld      a,(@adrv)\r
        add     a,'A'\r
        ld      c,a\r
-       call    ?cono   ; drive code\r
+       call    ?cono           ; drive code\r
        ld      hl,track$msg\r
-       call    ?pmsg                   ; track header\r
+       call    ?pmsg           ; track header\r
+       ld      c,0\r
        ld      hl,(@trk)\r
-       call    ?pdec                           ; track number\r
+       call    pr.dec          ; track number\r
        ld      hl,sector$msg\r
-       call    ?pmsg                   ; sector header\r
+       call    ?pmsg           ; sector header\r
        ld      hl,(@sect)\r
-       call    ?pdec                           ; sector number\r
+       call    pr.dec          ; sector number\r
        ret\r
 \r
 \r
@@ -622,9 +677,9 @@ table10:
        ;       Bank Select.  Select CPU bank for further execution.\r
 \r
 bnksel:\r
-       ld      (@cbnk),a               ; remember current bank\r
-       jp      ?bank                   ; and go exit through users\r
-                                       ; physical bank select routine\r
+       ld      (@cbnk),a       ; remember current bank\r
+       jp      ?bank           ; and go exit through users\r
+                               ; physical bank select routine\r
 \r
 \r
 xofflist:\r
@@ -648,34 +703,34 @@ xofflist:
        ;               in <HL>\r
 \r
 seldsk:\r
-       ld      a,c                     ; save drive select code\r
+       ld      a,c             ; save drive select code\r
        ld      (@adrv),a\r
-       ld      b,0                     ; create index from drive code\r
+       ld      b,0             ; create index from drive code\r
        ld      hl,@dtbl\r
-       add     hl,bc                   ; get pointer to dispatch table\r
+       add     hl,bc           ; get pointer to dispatch table\r
        add     hl,bc\r
        ld      a,(hl)\r
        inc     hl\r
        ld      h,(hl)\r
-       ld      l,a                     ; point at disk descriptor\r
-       ld      (@xdph),hl              ; save descriptor pointer\r
+       ld      l,a             ; point at disk descriptor\r
+       ld      (@xdph),hl      ; save descriptor pointer\r
        or      h\r
-       ret     z                       ; if no entry in table, no disk\r
+       ret     z               ; if no entry in table, no disk\r
 \r
-       ld      a,e                     ; examine login bit\r
+       ld      a,e             ; examine login bit\r
        and     1\r
        ret     nz\r
 \r
        push    ix\r
        ld      ix,(@xdph)\r
        ld      a,(ix-2)\r
-       ld      (@RDRV),a               ; get relative drive\r
-       ld      l,(ix-6)                ; get address of LOGIN routine\r
+       ld      (@RDRV),a       ; get relative drive\r
+       ld      l,(ix-6)        ; get address of LOGIN routine\r
        ld      h,(ix-5)\r
        ex      (sp),ix\r
        pop     de\r
-       call    ipchl                   ; call LOGIN\r
-       ld      hl,(@xdph)              ; recover DPH pointer\r
+       call    ipchl           ; call LOGIN\r
+       ld      hl,(@xdph)      ; recover DPH pointer\r
        ret\r
 \r
 \r
@@ -751,8 +806,8 @@ sectrn:
        ;               extended disk parameter header (XDPH).\r
 \r
 read:\r
-       ld      ix,(@xdph)              ; get drive descriptor pointer\r
-       ld      l,(ix-8)                ; get read routine entry\r
+       ld      ix,(@xdph)      ; get drive descriptor pointer\r
+       ld      l,(ix-8)        ; get read routine entry\r
        ld      h,(ix-7)\r
        jp      (hl)\r
 \r
@@ -763,8 +818,8 @@ read:
        ;               extended disk parameter header (XDPH).\r
 \r
 write:\r
-       ld      ix,(@xdph)              ; get drive descriptor pointer\r
-       ld      l,(ix-10)               ; get write routine entry\r
+       ld      ix,(@xdph)      ; get drive descriptor pointer\r
+       ld      l,(ix-10)       ; get write routine entry\r
        ld      h,(ix- 9)\r
        jp      (hl)\r
 \r
@@ -784,7 +839,7 @@ multio:
 \r
 flush:\r
        xor     a\r
-       ret             ; return with no error\r
+       ret                     ; return with no error\r
 \r
 \r
 \r