PAGE 66,132
TITLE RBBS-PC Assembly Language Subroutines Copyright 1986, by D. Thomas Mack
;--------------------------------------------------------------------;
;ROUTINE: RBBSFIND            AUTHOR:  D. Thomas Mack                ;
;                                      10210 Oxfordshire Road        ;
;                                      Great Falls, Virginia  22066  ;
;                                                                    ;
;DATE:  June 29, 1986         VERSION: 1.0                           ;       
;                                                                    ;
;FUNCTION: This routine supports calls from the IBM (MICROSOFT)      ;
;          BASIC Version 2.0 or Microsoft Quick BASIC Version 1.0    ;
;          compilers to find the date a file was created.            ;
;                                                                    ;
;            CALL RBBSFIND (A$,ERROR%,YEAR%,MONTH%,DAY%)             ;
;                                                                    ;
;          where A$ is the fully qualified file name to find the     ;
;                   date for and all other parameters are zeroes.    ;
;                                                                    ;
; Offset   Variable    Description of Variable                       ;
;                                                                    ;
; BP+14       BX  = string descriptor address of the file name to    ;
;                   find the creation date for where the string      ;
;                   descriptior has the format:                      ;
;                                                                    ;
;                   Bytes 0 and 1 contain the length of the string   ;
;                                 (0 to 32,767).                     ;
;                   Bytes 2 and 3 contain the lower and upper 8 bits ;
;                                 of the string's starting address   ;
;                                 in string space (respectively).    ;
; BP+12   ERROR% = Zero if no error was encountered.  Non-zero if an ;
;                  error occurred.                                   ;
; BP+10    YEAR% = number of years since 1980 when file was last     ;
;                  modified.
; BP+8    MONTH% = month the file was last modified.                 ;
; BP+6      DAY% = day the file was last modified.                   ;
;                                                                    ;
;--------------------------------------------------------------------;
;
; LIST OF PARAMETERS AS THEY APPEAR ON THE STACK
;
PARMLIST STRUC
SAVE_BP   DW     ?             ;RETAINS CONTENTS OF BASE POINTER REGISTER
RET_OFF   DW     ?             ;RETURN ADDRESS OF CALLING PROGRAM
RET_SEG   DW     ?             
PARM5     DW     ?             ;DAY FILE WAS CREATED
PARM4     DW     ?             ;MONTH FILE WAS CREATED
PARM3     DW     ?             ;YEAR FILE WAS CREATED (PAST 1980)
PARM2     DW     ?             ;ERROR RETURN CODE
PARM1     DW     ?             ;STRING DESCRIPTOR
PARMLIST  ENDS
;
; LET THE ASSEMBLER CALCULATE THE VALUE FOR RETURNING FROM SUBROUTINE WITH EQU
;
PARMSIZE  EQU    OFFSET PARM1 - OFFSET RET_SEG
;
; LOCAL DATA AREA FOR INITIALIZED CONSTANTS (NONE)
;
CONST     SEGMENT WORD PUBLIC 'CONST'
CONST     ENDS
;
; LOCAL DATA AREA OF UNINITIALIZED VALUES
; 
DATA      SEGMENT WORD PUBLIC 'DATA'
SAVE_DTA_OFF DW  ?             ;ADDRESS OF CURRENT DISK TRANSFER AREA
SAVE_DTA_SEG DW  ?      
RBBSDTA      DB 30 DUP(?)      ;WORKING DTA (NOT BASIC'S)
PATHFILE     DB 64 DUP(?)      ;PATH AND FILE NAME FOR SEARCH
DATA      ENDS
DGROUP    GROUP DATA,CONST
;
; DEFINE A STACK TO PUSH UP TO 3 ITEMS ON THE STACK AT ANY GIVEN TIME
;
STACK     SEGMENT WORD STACK 'STACK'
          DW      4 DUP(?)
STACK     ENDS
RBBS_UTIL SEGMENT BYTE PUBLIC 'CODE'
          ASSUME  CS:RBBS_UTIL,DS:DGROUP
RBBSFIND  PROC   FAR           ;LONG CALL
          PUBLIC RBBSFIND
          PUSH   BP            ;SAVE CALLER'S BASE POINTER REGISTER -- BP 
          MOV    BP,SP         ;SETUP TO ADDRESS OFF OF BASE POINTER REGISTER
          MOV    BX,[BP].PARM1 ;GET FILE NAME STRING DESCRIPTOR ADDRESS
          MOV    CX,[BX]       ;GET THE SIZE OF THE STRING
          XOR    AX,AX         ;INDICATE NO ERROR CONDITIONS
          CMP    CX,0          ;IF LENGTH IS ZERO,
          JE     FINISH        ;EXIT
;
          MOV    SI,[BX+2]     ;GET THE ADDRESS OF THE STRING
          PUSH   DS            ;PUSH DATA SEGMENT REGISTER -- DS, 
          POP    ES            ;INTO EXTENDED SEGMENT REGISTER -- ES, FOR MOVE
          LEA    DI,PATHFILE   ;MOVE PATH/FILE SPECIFICATION TO "PATHFILE" AREA
          CLD                  ;CLEAR DIRECTION FLAGS
          REP    MOVSB         ;END STRING WITH A BINARY ZERO FOR DOS CALL
          MOV    BYTE PTR ES:[DI],0
;
          MOV    AH,2FH        ;GET DISK TRANSFER AREA ADDRESS IN BX
          INT    21H           ;ISSUE DOS INTERRUPT 21
          JC     FINISH        ;EXIT IF THERE WERE ERRORS
          MOV    SAVE_DTA_OFF,BX ;SAVE BASIC'S DISK TRANSFER AREA
          MOV    SAVE_DTA_SEG,ES
;
          LEA    DX,RBBSDTA    ;SET UP PRIVATE DISK TRANSFER AREA FROM BASIC'S
          MOV    AH,1AH        ;SETUP NEW TEMPORARY DISK TRANSFER AREA ADDRESS
          INT    21H           ;ISSUE DOS INTERRUPT 21
          JC     FINISH        ;EXIT IF THERE WERE ERRORS 
;
          XOR    CX,CX         ;SET UP TO LOOK FOR ALL DIRECTORY ENTRIES
          LEA    DX,PATHFILE   ;FIND THE FIRST FILE THAT MATCHES "PATHFILE"
          MOV    AH,4EH        ;CALL DOS FUNCTION X'4E' TO FIND FILE
          INT    21H           ;ISSUE DOS INTERRUPT 21
          JC     EXIT          ;EXIT IF THERE WHERE ERRORS
;
          LEA    DI,RBBSDTA+24 ;POINT TO DATE FIELD IN DISK TRANSFER AREA (+24)
          MOV    AX,DS:[DI]    ;GET DATE OF FILE (DTA +24) IN AX REGISTER
;                               BITS 0-4  = DAY(1-31)
;                               BITS 5-8  = MONTH(1-12)
;                               BITS 9-15 = YEAR(0 - 119, AS AN OFFSET OF 1980)
;      SET UP AS FOLLOWS:
;
;      |<-------YEAR------->|<--MONTH-->|<-----DAY---->|
;      |15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0|
;      |           |           |           |           | 
;        0  0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  = X'01E0'  
;        0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  = X'001F'

          MOV    BX,AX         ;GET THE DATE INTO THE BX REGISTER
          MOV    CL,9          ;PREPARE TO SHIFT RIGHT NINE BITS (0-8)
          SHR    BX,CL         ;SHIFT RIGHT NINE BITS LEAVING THE YEAR ONLY
          MOV    DI,[BP].PARM3 ;GET ADDRESS OF WHERE TO PUT YEAR (AS AN INDEX 
          MOV    [DI],BX       ;PAST 1980) FILE WAS CREATED AND PASS IT BACK
;
          MOV    BX,AX         ;GET THE DATE INTO THE BX REGISTER AGAIN
          AND    BX,01E0H      ;TURN OFF ALL THE BITS EXCEPT BITS 5-8 (MONTH)
          MOV    CL,5          ;PREPARE TO SHIFT RIGHT FIVE BITS (0-4)
          SHR    BX,CL         ;SHIFT RIGHT FIVE BITS TO GET MONTH ONLY
          MOV    DI,[BP].PARM4 ;GET ADDRESS OF WHERE TO PUT MONTH FILE WAS MADE
          MOV    [DI],BX       ;PASS BACK THE MONTH THE FILE WAS CREATED
;
          AND    AX,001FH      ;TURN OFF ALL THE BITS EXCEPT BITS 0-4 (THE DAY)
          MOV    DI,[BP].PARM5 ;GET ADDRESS OF WHERE TO PUT DAY FILE WAS MADE
          MOV    [DI],AX       ;PASS BACK THE DAY THE FILE WAS CREATED
          XOR    AX,AX         ;INDICATE NO ERROR CONDITIONS

;
EXIT:     PUSH   AX            ;SAVE ERROR INDICATOR REGISTER -- AX
          PUSH   DS            ;SAVE DATA SEGMENT REGISTER -- DS
          MOV    DX,SAVE_DTA_OFF ;RESTORE BASIC'S DISK TRANSFER AREA AFTER  CPC151A7+
          MOV    DS,SAVE_DTA_SEG ;SETTING UP THE TEMPORARY RBBS-PC ONE      CPC151A7+
          MOV    AH,1AH        ;CALL DOS FUNCTION '1A' TO CHANGE DTA'S
          INT    21H          ;ISSUE DOS INTERRUPT 21                      CPC151A7+
          POP    DS            ;RESTORE DATA SEGMENT REGISTER -- DS
          POP    AX            ;RESTORE ERROR INDICATOR REGISTER -- AX
;
FINISH:   MOV    DI,[BP].PARM2 ;GET ADDRESS OF WHERE TO PUT ERROR RETURN CODE
          MOV    [DI],AX       ;PUT THE ERROR RETURN CODE IN ERROR%
          POP    BP            ;RESTORE CALLERS BASE POINTER REGISTER-- BP
          RET    PARMSIZE      ;RETURN AND REMOVE THE 5 PARAMETERS FROM STACK
RBBSFIND  ENDP
;--------------------------------------------------------------------;
;ROUTINE: RBBSULC             AUTHOR:  D. Thomas Mack                ;
;                                      10210 Oxfordshire Road        ;
;                                      Great Falls, Virginia  22066  ;
;                                                                    ;
;DATE:  June 29, 1986         VERSION: 1.0                           ;       
;                                                                    ;
;FUNCTION: This routine supports calls from the IBM (MICROSOFT)      ;
;          BASIC Version 2.0 or Microsoft Quick BASIC Version 1.0    ;
;          compilers to convert a string to upper case alphabetic    ;
;          characters.                                               ;
;                                                                    ;
;            CALL RBBSULC (A$)                                       ;
;                                                                    ;
;          where A$ is the string to be converted to upper case.     ;
;                                                                    ;
; Offset   Variable    Description of Variable                       ;
;                                                                    ;
; BP+6        BX  = string descriptor address where the string       ;
;                   descriptor has the format:                       ;
;                                                                    ;
;                   Bytes 0 and 1 contain the length of the string   ;
;                                 (0 to 32,767).                     ;
;                   Bytes 2 and 3 contain the lower and upper 8 bits ;
;                                 of the string's starting address   ;
;                                 in string space (respectively).    ;
;                                                                    ;
;--------------------------------------------------------------------;
RBBSULC   PROC   FAR           ;LONG CALL
          PUBLIC RBBSULC
          PUSH   BP            ;SAVE CALLERS BASE POINTER REGISTER -- BP 
          MOV    BP,SP         ;SETUP TO ADDRESS OFF OF BASE POINTER REGISTER
          MOV    BX,[BP+6]     ;GET A$ STRING DESCRIPTOR ADDRESS
          MOV    CX,[BX]       ;GET LENGTH OF STRING A$ IN CX REGISTER
          MOV    DI,2[BX]      ;GET ADDRESS OF STRING A$ IN DATA INDEX 
          CMP    CX,0          ;IF LENGTH IS ZERO (I.E. PASSED A NULL STRING)
          JZ     DONE          ;EXIT
LOOP:     MOV    AL,[DI]       ;GET A CHARACTER.
          CMP    AL,'a'        ;IF LESS THAN A LOWER CASE "A" DON'T CHANGE. 
          JL     NEXT          ;JUMP TO GET THE NEXT CHARACTER.    
          CMP    AL,'z'        ;IF GREATER THAN A LOWER CASE "Z" DON'T CHANGE.
          JA     NEXT          ;JUMP TO GET THE NEXT CHARACTER.
LOWER:    SUB    AL,32         ;SUBTRACT 32 FROM VALUE IF A LOWER CASE LETTER.
          MOV    [DI],AL       ;STORE THE VALUE IN THE STRING AREA.
NEXT:     INC    DI            ;POINT TO THE NEXT CHARACTER OF THE STRING.
          LOOP   LOOP          ;NOW GO BACK TO TEST THE NEXT CHARACTER.
DONE:     POP    BP            ;RESTORE CALLERS BASE POINTER REGISTER-- BP
          RET    2             ;RETURN AND REMOVE THE 1 PARAMETES FROM STACK
RBBSULC   ENDP
;--------------------------------------------------------------------;
;ROUTINE: RBBSFREE            AUTHOR:  D. Thomas Mack                ;
;                                      10210 Oxfordshire Road        ;
;                                      Great Falls, Virginia  22066  ;
;                                                                    ;
;DATE:  June 29, 1986         VERSION: 1.0                           ;       
;                                                                    ;
;FUNCTION: This routine supports calls from the IBM (MICROSOFT)      ;
;          BASIC Version 2.0 or Microsoft Quick BASIC Version 1.0    ;
;          compilers to DOS interrupt 36 to find the amount of free  ;
;          space on a specific disk drive.                           ;
;                                                                    ;
;            CALL RBBSFREE (AX%,BX%,CX%,DX%)                         ;
;                                                                    ;
;          where AX% and BX% are 16-bit binary data items (i.e.      ;
;          integer variables) and should be as follows:              ;
;                                                                    ;
; Offset   Variable    Description of Variable                       ;
;                                                                    ;
; BP+12       AX% = number of the disk drive to find the free space  ;
;                   for where 0=default drive, 1=A, 2=B, etc.        ;
;                                                                    ;
; BP+10       BX% = zero when calling RBBSFREE                       ;
; BP+8        CX% = zero when calling RBBSFREE                       ;
; BP+6        DX% = zero when calling RBBSFREE                       ;
;                                                                    ;
;          upon returning from RBBSFREE, these are set as follows:   ;
;                                                                    ;
;             AX% = if the drive specified was invalid contains the  ;
;                   hexadecimal value of FFFF.  If the drive was     ;
;                   valid contains the number of sectors per cluster.;
;             BX% = contains the number of available clusters.       ;
;             CX% = contains the number of bytes per sector.         ;
;             DX% = contains the total number of clusters on the     ;
;                   drive.                                           ;
;           FREESPACE = AX%*BX%*CX% IF AX%<> X'FFFF'                 ;
;--------------------------------------------------------------------;
RBBSFREE  PROC   FAR           ;LONG CALL
          PUBLIC RBBSFREE
          PUSH   BP            ;SAVE CALLERS BASE POINTER REGISTER -- BP 
          MOV    BP,SP         ;SETUP TO ADDRESS OFF OF BASE POINTER REGISTER
          MOV    DI,[BP+12]    ;GET ADDRESS OF AX% PARAMETER
          MOV    DL,[DI]       ;PUT VALUE IN DL REGISTER OF DISK DRIVE
          MOV    AH,36H        ;CALL DOS FUNCTION 36 TO GET FREE DISK SPACE
          INT    21H           ;ISSUE DOS INTERRUPT 21 
          MOV    DI,[BP+12]    ;GET ADDRESS OF AX% PARAMETER
          MOV    [DI],AX       ;PUT VALUE OF AX IN AX% PARAMETER
          MOV    DI,[BP+10]    ;GET ADDRESS OF BX% PARAMETER
          MOV    [DI],BX       ;PUT VALUE OF BX IN BX% PARAMETER
          MOV    DI,[BP+8]     ;GET ADDRESS OF CX% PARAMETER
          MOV    [DI],CX       ;PUT VALUE OF CX IN CX% PARAMETER
          MOV    DI,[BP+6]     ;GET ADDRESS OF DX% PARAMETER
          MOV    [DI],DX       ;PUT VALUE OF DX IN DX% PARAMETER
          POP    BP            ;RESTORE CALLERS BASE POINTER REGISTER-- BP
          RET    8             ;RETURN AND REMOVE THE 4 PARAMETERS FROM STACK
RBBSFREE  ENDP
;--------------------------------------------------------------------;
;ROUTINE: RBBSDOS             AUTHOR:  D. Thomas Mack                ;
;                                      10210 Oxfordshire Road        ;
;                                      Great Falls, Virginia  22066  ;
;                                                                    ;
;DATE:  June 29, 1986         VERSION: 1.0                           ;       
;                                                                    ;
;FUNCTION: This routine supports calls from the IBM (MICROSOFT)      ;
;          BASIC Version 2.0 or Microsoft Quick BASIC Version 1.0    ;
;          compilers to DOS interrupt 33 to find the version of DOS  ;
;          that RBBS-PC is being run under.                          ;
;                                                                    ;
;            CALL RBBSDOS (AX%,BX%)                                  ;
;                                                                    ;
;          where AX% and BX% are 16-bit binary data items (i.e.      ;
;          integer variables) and should be as follows:              ;
;                                                                    ;
; Offset   Variable    Description of Variable                       ;
;                                                                    ;
; BP+8        AX% = major version number of the DOS that RBBS-PC is  ;
;                   running under.  (Zero if less than DOS 2.0)      ;
;                                                                    ;
; BP+6        BX% = minor version under of the DOS that RBBS-PC is   ;
;                   running under.                                   ;
;--------------------------------------------------------------------;
RBBSDOS   PROC   FAR           ;LONG CALL
          PUBLIC RBBSDOS
          PUSH   BP            ;SAVE CALLERS BASE POINTER REGISTER -- BP 
          MOV    BP,SP         ;SETUP TO ADDRESS OFF OF BASE POINTER REGISTER
          MOV    AH,30H        ;CALL DOS FUNCTION 30 TO GET DOS VERSION
          INT    21H           ;ISSUE DOS INTERRUPT 21 
          MOV    DI,[BP+8]     ;GET ADDRESS OF AX% PARAMETER
          MOV    [DI],AL       ;PUT VALUE OF MAJOR DOS NUMBER IN AX% PARAMETER
          MOV    DI,[BP+6]     ;GET ADDRESS OF BX% PARAMETER
          MOV    [DI],AH       ;PUT VALUE OF MINOR DOS VERSION IN B% PARAMETER
          POP    BP            ;RESTORE CALLERS BASE POINTER REGISTER-- BP
          RET    4             ;RETURN AND REMOVE THE 2 PARAMETERS FROM STACK
RBBSDOS   ENDP
RBBS_UTIL ENDS
          END
