home *** CD-ROM | disk | FTP | other *** search
/ Software Du Jour / SoftwareDuJour.iso / BUSINESS / DBASE / DBAPG.ARC / DISKSTAT.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-08-06  |  12.5 KB  |  293 lines

  1. ; Subroutine.: DISKSTAT.ASM
  2. ; Author.....: Kelly Mc Tiernan
  3. ; Date.......: 1983
  4. ; Notice.....: Copyright 1983, Kelly Mc Tiernan, All Rights Reserved
  5. ; Notes......: CP/M-80 disk drive status routine.
  6. ;
  7. BDOS    EQU     00005H
  8. FDPB    EQU     1FH
  9. FALV    EQU     1BH
  10. FDSK    EQU     19H
  11. FCHG    EQU     0EH
  12. ;
  13.         ORG     42000
  14. ;
  15. START:  SHLD    SAVEHL          ; SAVE HL REG PAIR
  16.         MVI     C,FDSK          ; DETERMINE CURRENT DISK 
  17.         PUSH    H               ; SAVE HL 
  18.         CALL    BDOS            ; 
  19.         STA     SAVDSK          ; AND SAVE TO RESTORE
  20.         POP     H               ; GET IT BACK
  21.         INX     H               ; POINT TO FIRST BYTE OF VARIABLE
  22.         MOV     A,M             ; GET IT
  23.         ORA     A               ; CLEAR CARRY
  24.         SBI     41H             ; CONVERT ASCII A,B,C TO 0,1,2,..
  25.         CPI     10H             ; LEGAL DRIVE NAME?
  26.         JNC     KEEPDR          ; NO, KEEP CURRENT DRIVE
  27.         MOV     E,A             ; GET DRIVE TO SELECT
  28.         MVI     C,FCHG          ; SELECT FUNCTION
  29.         CALL    BDOS            ;
  30. ;
  31. KEEPDR: LXI     H,0000H         ; TO SAVE SP
  32.         DAD     SP              ; GET SP
  33.         SHLD    SAVESP          ; SAVE IT
  34.         MVI     A,01H           ; TO INIT. SIG. DIGIT POINTER
  35.         LXI     H,ANSWER        ; WHERE IT GOES
  36.         MOV     M,A             ; INITIALIZE
  37.         MVI     C,FDPB          ; GET DPB ADDRESS
  38.         CALL    BDOS            ; HL HAS ADDRESS
  39.         SHLD    DPBADR          ; SAVE BASE ADDRESS
  40.         LXI     B,0005H         ; OFFSET TO DSM
  41.         DAD     B               ; 
  42.         MOV     E,M             ; GET FIRST BYTE
  43.         INX     H               ; FOR NEXT BYTE
  44.         MOV     D,M             ; GET IT
  45.         XCHG                    ; GET WHERE IT CAN BE USED
  46.         MVI     B,03H           ; COUNT FOR SHIFT
  47. DIV8:   ORA     A               ; CLEAR CARRY FOR DIVISION
  48.         MOV     A,H             ; GET FIRST BYTE
  49.         RAR                     ; DIVIDE BY 2
  50.         MOV     H,A             ; RESTORE HIGH BYTE
  51.         MOV     A,L             ; GET LOW BYTE
  52.         RAR                     ; DIVIDE BY 2 (SHIFT IN HB CARRY)
  53.         MOV     L,A             ; RESTORE IT
  54.         DCR     B               ; FOR COUNT
  55.         JNZ     DIV8            ; CONTINUE 3 TIMES (2*2*2=8)
  56. è        INX     H               ; +1=ALV LENGTH
  57.         SHLD    ALVLNG          ; SAVE LENGTH OF ALV
  58. ;
  59. ; NOW CALCULATE BLOCK SIZE FOR DRIVE
  60. ;
  61.         LHLD    DPBADR          ; GET BACK BLOCK ADDRESS
  62.         INX     H               ; VECTOR INTO DPB FOR BSH
  63.         INX     H               ;
  64.         MOV     E,M             ; GET IT
  65.         MVI     D,00H           ; ZERO HB
  66.         DCX     D               ; FOR VECTOR INTO TABLE
  67.         DCX     D               ;
  68.         DCX     D               ;
  69.         MOV     A,E             ; GET IT
  70.         ORA     A               ; CLEAR CARRY
  71.         RAL                     ; MULTIPLY BY 2
  72.         MOV     E,A             ; GET BACK VECTOR 
  73.         LXI     H,TABLE         ; BASE ADDRESS
  74.         DAD     D               ; ADD IN VECTOR
  75.         MOV     E,M             ; GET LB (STORED LB,HB)
  76.         INX     H               ; NEXT BYTE
  77.         MOV     D,M             ; DE NOW CONTAINS BLOCK SIZE
  78.         XCHG                    ; GET IT TO WHERE WE CAN SAVE IT
  79.         SHLD    BLS             ; SAVE IT
  80. ;
  81. ;
  82. ; NOW LET'S DETERMINE SPACE LEFT ON DISK
  83. ;
  84.         MVI     C,FALV          ; LET'S GET ALV ADDRESS NOW
  85.         CALL    BDOS            ; HL CONTAINS ADDRESS
  86.         LDA     ALVLNG          ; GET LENGTH
  87.         MOV     B,A             ; INTO COUNTER 1
  88.         LXI     D,0000H         ; BIT COUNTER ZEROED
  89.         DCX     H               ; SET FOR LOOP CONTROL
  90.         SHLD    TEMP            ; SAVE HL
  91.         DI                      ; DISABLE INTERRUPTS BEFORE SP 
  92.                                 ; CHANGE
  93.         LHLD    BLS             ; GET BLOCK SIZE
  94.         SPHL                    ; FOR ADDITION
  95.         LXI     H,0000H         ; INITIALIZE
  96.         SHLD    SIZE0           ;   "   "
  97.         SHLD    SIZE1           ;   "   "
  98. BITCNT: LHLD    TEMP            ; RESTORE HL
  99.         INX     H               ; POINT TO BYTE
  100.         MVI     C,08H           ; COUNTER 2 FOR BITS/BYTE
  101.         MOV     A,M             ; GET FIRST BYTE
  102.         ORA     A               ; CLEAR CARRY
  103.         SHLD    TEMP            ; SAVE HL POINTER
  104. BIT1:   LHLD    SIZE0           ; GET LOW WORD TOTAL
  105.         RAR                     ; ROTATE A TO COUNT ZERO BITS
  106.         JC      BIT2            ; DON'T COUNT 1'S
  107.         DAD     SP              ; IF UNALLOC. THEN ADD 1 BLOCK 
  108.                                 ; TO TTL.
  109.         JNC     BIT2            ; IF NO CARRY FROM DAD H
  110.         INX     D               ; ELSE ADD 1 TO HIGH WORD
  111. èBIT2:   SHLD    SIZE0           ; SAVE NEW LOW WORD FOR UNALLOC.
  112.         DCR     C               ; COUNTER
  113.         JNZ     BIT1            ; NEXT BIT
  114.         DCR     B               ; COUNT FOR BYTES
  115.         JNZ     BITCNT          ; DO NEXT BYTE
  116.         XCHG                    ; GET HIGH WORD INTO HL
  117.         SHLD    SIZE1           ; SAVE IT
  118.         LHLD    SIZE0           ; FOR CORRECTION FACTOR
  119.         LXI     SP,0E000H       ; ERROR OFFSET
  120.         DAD     SP              ; TWO'S COMP. OF 2000H (SUBTRACT
  121.                                 ; OFFSET)
  122.         SHLD    SIZE0           ; SAVE RESULT
  123.         JC      EX1             ; EXIT IF CARRY (LOW WORD > 
  124.                                 ; 2000H)
  125.         LHLD    SIZE1           ; FOR BORROW
  126.         DCX     H               ; SUBTRACT 1
  127.         SHLD    SIZE1           ; SAVE RESULT 
  128. EX1:    LHLD    SAVESP          ; RESTORE STACK POINTER
  129.         SPHL                    ;
  130.         EI                      ; ENABLE INTERRUPTS 
  131. ;
  132. ;
  133. ; NOW WE CONVERT TO A DECIMAL STRING
  134. ;
  135.         LXI     H,ANSWER+1      ; TO INITIAIZE DATA AREA
  136.         MVI     B,0AH           ; COUNTER
  137.         MVI     A,00H           ; INITIALIZE TO 0
  138. INIT1:  MOV     M,A             ; 
  139.         INX     H               ; NEXT BYTE
  140.         DCR     B               ;
  141.         JNZ     INIT1           ; REPEAT FOR 10 BYTES
  142.         MVI     C,0AH           ; TOTAL # OF SIG DIGITS COUNTER
  143.         LXI     H,SIZE0         ; POINTER TO LOWEST BYTE
  144.         XCHG                    ; SAVE IT
  145.         LXI     H,TBL2          ; POINT TO SUBTRACTION TABLE
  146.         XCHG                    ; GET BACK DATA TABLE ADDRESS
  147. MINUS:  ORA     A               ; CLEAR CARRY FOR LOW BYTE
  148.         MVI     B,03H           ; COUNTER FOR SUBS
  149. MIN0:   MOV     A,M             ; GET DATA
  150.         XCHG                    ; GET SUB TABLE POINTER
  151.         SBB     M               ; SUBTRACT DIGIT
  152.         INX     H               ; POINT TO NEXT TABLE ENTRY
  153.         XCHG                    ; GET BACK DATA POINTER
  154.         MOV     M,A             ; PUT BACK RESULT
  155.         INX     H               ; POINT TO NEXT DATA BYTE
  156.         DCR     B               ; DONE WITH LOW 3 BYTES ?
  157.         JNZ     MIN0            ; CHECK FOR NEG ON LAST BYTE SBB
  158. LAST1:  MOV     A,M             ; GET MOST SIG BYTE
  159.         XCHG                    ; GET TABLE POINTER
  160.         SBB     M               ; SUBTRACT IT
  161.         DI                      ; DISABLE INTERUPTS BEFORE CALL
  162.         CP      AD1             ; ADD 1 TO SIG DIGIT IF IT WENT
  163.         EI                      ; ENABLE INTERUPTS ON RETURN
  164.         DCX     H               ; MOVE POINTER BACK TO BEGINNING
  165.         DCX     H               ; OF TABLE
  166. è        DCX     H               ;
  167.         XCHG                    ; GET BACK DATA POINTER
  168.         MOV     M,A             ; PUT BACK RESULT
  169.         DCX     H               ; MOVE POINTER BACK TO BEGINNING 
  170.         DCX     H               ; OF DATA
  171.         DCX     H               ; 
  172.         DI                      ; DISABLE INTERUPTS
  173.         CM      PUTBK           ; PUT BACK IF NEG AND MOVE ON
  174.         EI                      ; ENABLE INTERUPTS
  175.         DCR     C               ; ONLY TO OVERRIDE SBB M
  176.         INR     C               ;
  177.         JNZ     MINUS           ; NO, DO AGAIN
  178. ;
  179. ;
  180. ; NOW LETS CONVERT TO ASCII (ADD 30H) AND PASS BACK
  181. ; TO 10 DIGIT DBASE VARIABLE 
  182. ;
  183.         LXI     H,ANSWER+1      ; POINT TO ANSWER BUFFER
  184.         MVI     B,0AH           ; FOR ALL 10 BYTES
  185. FILL:   MVI     A,30H           ; TO CONVERT TO ASCII
  186.         ADD     M               ; UNPACKED BCD+30=ASCII
  187.         MOV     M,A             ; PUT CORRECTED ANSWER BACK
  188.         INX     H               ; NEXT DIGIT
  189.         DCR     B               ; DONE ?
  190.         JNZ     FILL            ;
  191.         LHLD    SAVEHL          ; OLD HL POINTER (VERY OLD)
  192.         MOV     A,M             ; LET'S DO A LITTLE ERROR 
  193.                                 ; CHECKING
  194.         CPI     0AH             ;
  195.         JNZ     ERROR           ; VARIABLE WRONG LENGTH
  196.         INX     H               ; NOW LET'S GIVE dBASE THE ANSWER
  197.         XCHG                    ; I KINDA LIKE THIS INSTRUCTION
  198.         LXI     H,ANSWER+1      ; SHOULD BE OBVIOUS BY NOW
  199.         MVI     B,0AH           ; COUNTER TO MOVE BYTES
  200. PASS:   MOV     A,M             ; GET BYTE
  201.         INX     H               ; FOR NEXT BYTE
  202.         XCHG                    ; WHERE TO SEND
  203.         MOV     M,A             ; SEND IT
  204.         INX     H               ; WHERE TO SEND NEXT ONE
  205.         XCHG                    ; BACK TO SOURCE POINTER
  206.         DCR     B               ; COUNTER FOR BYTES PASSED
  207.         JNZ     PASS            ; DO NEXT BYTE
  208.         JMP     FINIS           ; NORMAL END OF ROUTINE
  209. ERROR:  INX     H               ; POINT TO FIRST BYTE
  210.         MVI     A,'E'           ; ERROR CODE
  211.         MOV     M,A             ; SEND ERROR CODE TO DBASE
  212. FINIS:  LDA     SAVDSK          ; GET BACK DISK IN USE NO.
  213.         MOV     E,A             ; PUT IN E FOR BDOS CALL
  214.         MVI     C,FCHG          ; FUNCTION TO CHANGE DISK
  215.         CALL    BDOS            ; BACK TO ORIGINAL DRIVE
  216.         LHLD    SAVESP          ; RESTORE SP
  217.         SPHL                    ;
  218.         LHLD    SAVEHL          ; RESTORE HL
  219.         RET
  220. ;
  221. è;
  222. ;    SUBROUTINES FOR CALCULATIONS
  223. ;
  224. PUTBK:  ORA     A               ; CLEAR CARRY
  225.         MVI     B,04H           ; COUNTER FOR ADDS
  226. PUT1:   MOV     A,M             ; GET DATA
  227.         XCHG                    ; POINT TO SUB TABLE
  228.         ADC     M               ; ADD BACK IN AMMOUNT
  229.         INX     H               ; POINT TO NEXT SUB TABLE BYTE
  230.         XCHG                    ; BACK TO DATA POINTER
  231.         MOV     M,A             ; PUT BACK RESULT
  232.         INX     H               ; POINT TO NEXT DATA BYTE
  233.         DCR     B                       
  234.         JNZ     PUT1            ; NEXT BYTE
  235.         DCX     H               ; RESET DATA POINTER
  236.         DCX     H               ;
  237.         DCX     H               ;
  238.         DCX     H               ;
  239.         PUSH    H               ; SAVE HL
  240.         LXI     H,ANSWER        ; POINT TO SIG DIGIT POINTER
  241.         INR     M               ; INCREMENT TO NEXT DIGIT
  242.         POP     H               ; RESTORE HL
  243.         DCR     C               ; COUNT FOR SIG DIGITS DONE
  244.         RET                     ; RETURN TO CALLER
  245. ;
  246. AD1:    PUSH    PSW             ; SAVE REGISTERS
  247.         PUSH    B               ;
  248.         PUSH    D               ;
  249.         PUSH    H               ;                       
  250.         LXI     H,ANSWER        ; ANSWER TABLE
  251.         MOV     E,M             ; GET POSITION
  252.         MVI     D,00H           ; FOR VECTOR
  253.         DAD     D               ; VECTOR TO SIG DIGIT
  254.         INR     M               ; ADD 1 TO DIGIT
  255.         POP     H               ; RESTORE REGISTERS
  256.         POP     D               ;
  257.         POP     B               ;
  258.         POP     PSW             ;
  259.         RET                     ;
  260. SAVEHL: DS      2
  261. SAVESP: DS      2
  262. DPBADR: DS      2
  263. ALVLNG: DS      2
  264. BLS:    DS      2
  265. TEMP:   DS      2
  266. SAVDSK: DS      1
  267. ;
  268. TABLE:  DB      00H
  269.         DB      04H
  270.         DB      00H
  271.         DB      08H
  272.         DB      00H
  273.         DB      10H
  274.         DB      00H
  275. è        DB      20H
  276.         DB      00H
  277.         DB      40H
  278. ;
  279. SIZE0:   DS     2
  280. SIZE1:   DS     2
  281. ;
  282. ;
  283. ANSWER: DS      10H             ; TOTAL SIG DIGITS+POINTER
  284. ;
  285. TBL2:   DB      000H,0CAH,09AH,03BH
  286.         DB      000H,0E1H,0F5H,005H
  287.         DB      080H,096H,098H,000H
  288.         DB      040H,042H,00FH,000H
  289.         DB      0A0H,086H,001H,000H
  290.         DB      010H,027H,000H,000H
  291.         DB      0E8H,003H,000H,000H
  292.         DB      064H,000H,000H,000H
  293.         DB      00AH,000H,000H,000H
  294.         DB      001H,000H,000H,000H
  295. ;
  296. END
  297.