home *** CD-ROM | disk | FTP | other *** search
- List-
-
- ;=============================================================================
- ; Basic I/O Procedures
- ;
- ; These routines provide methods to manipulate strings and processes simple
- ; I/O. The procedures are completely MS/PC DOS compatible, the hardware or
- ; BIOS is never directly accessed (except for SOUND_SPK_P).
- ;
- ; All parameters are passed on the stack unless specified otherwise. All
- ; string addresses consist of a segment and offset (they are 32-bit). The
- ; offset should always be pushed on the stack first. If more than one string
- ; address is required, the destination string (the string to be modified)
- ; should be pushed on the stack first. Note that data may be returned on the
- ; stack as specified and should be removed by the programmer before, for
- ; instance, returning from a routine. Parameters will be returned even if an
- ; error occurs, though the data may not be valid.
- ;
- ; If a new string is created (for instance the time string), it will exist in
- ; a local buffer and the address that is returned on the stack will point to
- ; that buffer. Local buffers should never be written to, only read from.
- ;
- ; All registers are preserved (unless they are used to pass parameters). The
- ; flags are not explicitly preserved. Note particularly that the direction
- ; flag (DF) may be cleared. If an error is detected, the carry flag will be
- ; set and generally the operation will not be carried out.
- ;
- ; Strings are defined as any sequence of 0 to 255 characters preceded by a
- ; length byte, except for file names, which must be a sequence of characters
- ; terminated by a byte 00. These two string types are not interchangeable, the
- ; only routines that require the latter type are the routines that open,
- ; create, or delete files (OPEN_FIL_P, CREATE_FIL_P, and DELETE_FIL_P).
- ;
- ; The stack is used extensively and should have about 200 bytes free before
- ; pushing any parameters and calling the routines.
- ;
- ; String manipulation:
- ;
- ; CLEAR_STR_P clear a string
- ; TRUNCATE_STR_P truncate a string
- ; COPY_STR_P copy a string from one location to another
- ; APPEND_STR_P append a string to another
- ; APPEND_CHRS_P append characters to a string
- ; FORMAT_RGT_P append a string to another after formatting
- ; JUSTIFY_RGT_P append a string to another right justified
- ; LOWER_CHR_P make a character lower-case
- ; UPPER_CHR_P make a character upper-case
- ; MAKE_BIN_P translate a string to a binary number
- ; MAKE_DEC_P translate a binary number to a string
- ; DAY_STR_P get the string representing the day
- ; MONTH_STR_P get the string representing the month
- ; TIME_STR_P get the string representing the time
- ; MAKE_NAM_P translate a string into the file name format
- ; MAKE_STR_P translate a file string into normal format
- ;
- ; Keyboard:
- ;
- ; INPUT_STA_P return input status
- ; INPUT_CHR_P input a character
- ; INPUT_HID_P input a character without screen echo
- ; INPUT_STR_P input a string
- ;
- ; Display:
- ;
- ; HOME_CUR_P move the cursor home (1)
- ; LEFT_CUR_P move the cursor left (1)
- ; RIGHT_CUR_P move the cursor right (1)
- ; UP_CUR_P move the cursor up (1)
- ; DOWN_CUR_P move the cursor down (1)
- ; SAVE_CUR_P save the cursor position (1)
- ; RESTORE_CUR_P restore the cursor position (1)
- ; LOCATE_CUR_P move the cursor to a location (1)
- ; NORMAL_ATR_P change the attribute to normal (1)
- ; BOLD_ATR_P change the attribute to bold (1)
- ; UNDERLINE_ATR_P change the attribute to underline (1)
- ; BLINK_ATR_P change the attribute to blinking (1)
- ; REVERSE_ATR_P change the attribute to reverse video (1)
- ; CLEAR_SCR_P clear the screen and home the cursor (1)
- ; DISPLAY_CHR_P display a character
- ; LINE_P start a new display line
- ; DISPLAY_STR_P display a string
- ; DISPLAY_LIN_P display a string and start a new line
- ;
- ; Speaker:
- ;
- ; SOUND_BEL_P beep the speaker
- ; SOUND_SPK_P sound the speaker at freq. for duration (2)
- ;
- ; File:
- ;
- ; OPEN_FIL_P open a file
- ; CREATE_FIL_P create or truncate a file
- ; DELETE_FIL_P delete a file
- ; READ_FIL_P read from a file
- ; WRITE_FIL_P write to a file
- ; SEEK_FIL_P move a file read write pointer
- ; SIZE_FIL_P get the size of a file
- ; CLOSE_FIL_P close a file
- ; FREE_DSK_P return free disk space
- ;
- ; (1) Requires that ANSI.SYS or compatible device driver be installed.
- ; (2) Hardware specific, duration is dependent on a 4.77 MHz computer.
-
- ;================================================
- ; This creates a library header so this file can
- ; read by the dispatcher code in DISPATCH.ASM.
- ; The next two source lines vary depending
- ; whether or not the file is being included into
- ; the source file directly, or is being
- ; assembled separately as a runtime library.
-
- ;presently set up to be included directly
- If 0 ;set to 1 if external library,
- ;0 if included directly
- ;Include 'E:Library.Asm' ;add this line (remove semi-colon) if external
- ;library, remove line (turn it into comment
- ;by adding semi-colon) if included directly
-
- Dw Offset Clear_Str_P
- Dw Offset Truncate_Str_P
- Dw Offset Copy_Str_P
- Dw Offset Append_Str_P
- Dw Offset Append_Chrs_P
- Dw Offset Format_Rgt_P
- Dw Offset Justify_Rgt_P
- Dw Offset Lower_Chr_P
- Dw Offset Upper_Chr_P
- Dw Offset Make_Bin_P
- Dw Offset Make_Dec_P
- Dw Offset Day_Str_P
- Dw Offset Month_Str_P
- Dw Offset Time_Str_P
- Dw Offset Make_Nam_P
- Dw Offset Make_Str_P
- Dw Offset Input_Sta_P
- Dw Offset Input_Chr_P
- Dw Offset Input_Hid_P
- Dw Offset Input_Str_P
- Dw Offset Home_Cur_P
- Dw Offset Left_Cur_P
- Dw Offset Right_Cur_P
- Dw Offset Up_Cur_P
- Dw Offset Down_Cur_P
- Dw Offset Locate_Cur_P
- Dw Offset Normal_Atr_P
- Dw Offset Bold_Atr_P
- Dw Offset Underline_Atr_P
- Dw Offset Blink_Atr_P
- Dw Offset Reverse_Atr_P
- Dw Offset Clear_Scr_P
- Dw Offset Display_Chr_P
- Dw Offset Sound_Bel_P
- Dw Offset Line_P
- Dw Offset Display_Str_P
- Dw Offset Display_Lin_P
- Dw Offset Open_Fil_P
- Dw Offset Create_Fil_P
- Dw Offset Delete_Fil_P
- Dw Offset Read_Fil_P
- Dw Offset Write_Fil_P
- Dw Offset Seek_Fil_P
- Dw Offset Size_Fil_P
- Dw Offset Close_Fil_P
- Dw Offset Free_Dsk_P
- Dw Offset Sound_Spk_P
- Dw Offset Save_Cur_P
- Dw Offset Restore_Cur_P
- Endif
-
- ;================================================
- ; Set the length of the destination string to
- ; zero. The string address is returned on the
- ; stack.
-
- Clear_Str_P Proc Near
- Push Si
- Push Ds
- Push Bp ;save registers
-
- Mov Bp, Sp
- Mov Si, [Bp+10] ;get source offset
- Mov Ds, [Bp+8] ;get source segment
-
- Mov Byte [Si], 0 ;zero length
-
- Pop Bp
- Pop Ds
- Pop Si
- Clc ;no error
- Ret
- Endp ;Clear_Str_P
-
- ;================================================
- ; Set the length of the destination string to
- ; the specifed length. The length must in the
- ; low byte of the last word pushed on the
- ; stack. The string address is returned on the
- ; stack and also the flags are set by a
- ; comparision of the new and previous lengths.
-
- Truncate_Str_P Proc Near
- Push Ax
- Push Si
- Push Ds
- Push Bp ;save registers
-
- Mov Bp, Sp
- Mov Si, [Bp+14] ;get source offset
- Mov Ds, [Bp+12] ;get source segment
- Mov Al, [Bp+10] ;get new length
- Mov Ah, Al
- Xchg Al, [Si] ;set new length and get old
-
- Cmp Al, Ah ;compare sizes, set flags
-
- Pop Bp
- Pop Ds
- Pop Si
- Pop Ax
- Ret 2
- Endp ;Truncate_Str_P
-
- ;================================================
- ; Copy the source string to the destination.
- ; The destination string address is returned on
- ; the stack.
-
- Copy_Str_P Proc Near
- Push Cx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Di, [Bp+20] ;get destination offset
- Mov Es, [Bp+18] ;get destination segment
- Mov Si, [Bp+16] ;get source offset
- Mov Ds, [Bp+14] ;get source segment
-
- Mov Cl, [Si] ;length
- Sub Ch, Ch
- Inc Cx ;include length byte
- Rep
- Movsb ;move string
-
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Cx ;restore registers
- Clc ;no error
- Ret 4
- Endp ;Copy_Str_P
-
- ;================================================
- ; Append the source string to the destination
- ; string. The destination string address is
- ; returned on the stack. The carry is set if
- ; the string would be too long.
-
- Append_Str_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Di, [Bp+24] ;get destination offset
- Mov Es, [Bp+22] ;get destination segment
- Mov Si, [Bp+20] ;get source offset
- Mov Ds, [Bp+18] ;get source segment
-
- Seg Es
- Mov Al, [Di] ;destination length
- Mov Cl, [Si] ;source length
- Sub Ah, Ah
- Mov Ch, Ah
-
- Mov Bx, Ax
- Add Al, Cl ;new total length
- Jc AppendStrError ;jump if too big
-
- Seg Es
- Mov [Di], Al ;save new length
-
- Add Di, Bx ;destination pointer to end
- Inc Di ;don't forget length byte
- Inc Si ;... and source
-
- Rep
- Movsb ;move string
- Clc ;no error
-
- AppendStrError
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret 4
- Endp ;Append_Str_P
-
- ;================================================
- ; Append some number of characters to the
- ; destination string. The character to append
- ; must be in the high byte of the last word
- ; pushed on the stack and the byte count must
- ; be in the low byte. The string address is
- ; returned on the stack. The carry is set if
- ; the string would be too long.
-
- Append_Chrs_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Di
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Di, [Bp+18] ;get destination offset
- Mov Es, [Bp+16] ;get destination segment
- Mov Cl, [Bp+14] ;get number of characters to append
-
- Seg Es
- Mov Al, [Di] ;destination length
- Sub Ah, Ah
- Mov Ch, Ah
-
- Mov Bx, Ax
- Add Al, Cl ;new total length
- Jc AppendChrError ;jump if too big
-
- Seg Es
- Mov [Di], Al ;save new length
-
- Add Di, Bx ;pointer to end
- Inc Di ;length byte
-
- Mov Al, [Bp+15] ;get character
- Rep
- Stosb ;store
- Clc ;no error
-
- AppendChrError
- Pop Bp
- Pop Es
- Pop Di
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret 2
- Endp ;Append_Chrs_P
-
- ;================================================
- ; Append a right justified source string to the
- ; destination string. Note that the source
- ; string is justified itself before it is
- ; appended. The character to use in justifing
- ; must be in the high byte of the last word
- ; pushed on the stack and the final source
- ; string size must be in the low byte. The
- ; destination string address is returned on the
- ; stack. The carry is set if the final string
- ; would be too long or could not be formatted.
-
- Format_Rgt_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Di, [Bp+26] ;get destination offset
- Mov Es, [Bp+24] ;get destination segment
- Mov Si, [Bp+22] ;get source offset
- Mov Ds, [Bp+20] ;get source segment
-
- ;--- add the justifing characters
-
- Seg Es
- Mov Al, [Di] ;destination length
- Mov Bh, [Si] ;source length
- Add Al, Bh ;length of two strings
- Jc FormatRgtError ;jump if too big
- Mov Bl, [Bp+18] ;get final source size
- Sub Bl, Bh ;calculate amount of justify
- Jc FormatRgtError ;jump if too small
- Add Al, Bl ;final total length
- Jc FormatRgtError ;jump if too big
- Mov Bh, [Bp+19] ;get character to justify with
-
- Push Di
- Push Es
- Push Bx
- Call Append_Chrs_P ;append characters
- Add Sp, 4 ;throw away address, not needed
-
- ;--- append the string
-
- Seg Es
- Mov Al, [Di] ;destination length
- Mov Cl, [Si] ;source length
- Sub Ah, Ah
- Mov Ch, Ah ;clear high bytes of sizes
-
- Mov Bx, Ax
- Add Al, Cl ;new total length
-
- Seg Es
- Mov [Di], Al ;save new length
-
- Add Di, Bx ;destination pointer to end
- Inc Di ;don't forget length byte
- Inc Si ;... and source
-
- Rep
- Movsb ;move string
- Clc ;no error
-
- FormatRgtError
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret 6
- Endp ;Format_Rgt_P
-
- ;================================================
- ; Append the source string to the destination
- ; string right justified. The character to use
- ; in justifing must be in the high byte of the
- ; last word pushed on the stack and the final
- ; string size must be in the low byte. The
- ; destination string address is returned on the
- ; stack. The carry is set if the final string
- ; would be too long or could not be justified.
-
- Justify_Rgt_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Di, [Bp+26] ;get destination offset
- Mov Es, [Bp+24] ;get destination segment
- Mov Si, [Bp+22] ;get source offset
- Mov Ds, [Bp+20] ;get source segment
-
- Seg Es
- Mov Al, [Di] ;destination length
- Mov Cl, [Si] ;source length
-
- ;--- add the justifing characters
-
- Mov Bh, Al
- Add Bh, Cl ;length of both strings in BL
- Jc Badjustify ;jump if too big
- Mov Bl, [Bp+18] ;get final size
- Sub Bl, Bh ;calculate amount of justify
- Jc Badjustify ;jump if final size too small
- Mov Bh, [Bp+19] ;get character to justify with
-
- Push Di
- Push Es
- Push Bx
- Call Append_Chrs_P ;append characters
- Add Sp, 4 ;throw away address, not needed
-
- ;--- append the string
-
- Sub Ah, Ah
- Mov Bh, Ah
- Mov Ch, Bh ;clear high bytes of sizes
-
- Add Ax, Bx ;add for new characters
- Mov Bx, Ax
- Add Al, Cl ;new total length
-
- Seg Es
- Mov [Di], Al ;save new length
-
- Add Di, Bx ;destination pointer to end
- Inc Di ;don't forget length byte
- Inc Si ;... and source
-
- Rep
- Movsb ;move string
- Clc ;no error
-
- BadJustify
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret 6
- Endp ;Justify_Rgt_P
-
- ;================================================
- ; Convert character in AL to lower-case. AL not
- ; preserved.
-
- Lower_Chr_P Proc Near
- Cmp Al, 'A' ;lower limit
- Jb NotLowerChr
- Cmp Al, 'Z' ;upper limit
- Ja NotLowerChr
- Add Al ,'a'-'A' ;make lower
- NotLowerChr Ret
- Endp ;Lower_Chr_P
-
- ;================================================
- ; Convert character in AL to upper-case. AL not
- ; preserved.
-
- Upper_Chr_P Proc Near
- Cmp Al, 'a' ;lower limit
- Jb NotUpperChr
- Cmp Al, 'z' ;upper limit
- Ja NotUpperChr
- Sub Al ,'a'-'A' ;make upper
- NotUpperChr Ret
- Endp ;Upper_Chr_P
-
- ;================================================
- ; Translate the destination string into a 32-
- ; bit number. The number is returned on the
- ; stack in place of the string address (the
- ; high 16 bits should be popped first). If
- ; there is an error the carry is set and a
- ; particular value is returned in the low word
- ; of the value: 0000 means the source was a nul
- ; string, 0001 means overflow, and 0002 means
- ; there was a bad character in the string.
-
- Make_Bin_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Di
- Push Si
- Push Ds
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Bp, Sp
- Mov Si, [Bp+20] ;get source offset
- Mov Ds, [Bp+18] ;get source segment
-
- Cmp Byte [Si], 0 ;check if nul string
- Je MakeBinNul ;jump if so
-
- Mov Bx, 10 ;base ten
- Lodsb ;load length
- Mov Cl, Al
- Sub Ch, Ch ;CX has length
-
- Sub Dx, Dx
- Mov Di, Dx ;expects value in DX.DI
- Jmp MakeBinStart ;jump to start, skip value x 10
-
- ;--- loop for each digit
-
- ;--- multiply total times ten
-
- MakeBinLoop
- Mov Ax, [Bp+18] ;high word of value
- Mul Ax, Bx ;multply, AX has high word result
- Jc MakeBinOver ;jump if overflow
- Mov Di, Ax ;save high word
-
- Mov Ax, [Bp+20] ;low word of value
- Mul Ax, Bx ;multiply, DX.AX has result
-
- Add Dx, Di ;add high result
- Jc MakeBinOver ;jump if overflow
-
- Mov Di, Ax ;save low word, new value is in DX.DI
-
- ;--- add in next digit
-
- MakeBinStart
- Lodsb ;load next digit
- Sub Al, '0' ;get value
- Cmp Al, 9 ;check value
- Ja MakeBinBad ;jump if illegal character
-
- Sub Ah, Ah
- Add Di, Ax ;add in new value
- Jnc MakeBinNohi ;jump if no carry to high word
-
- Inc Dx ;increment high word
- Jz MakeBinOver ;jump if overflow
-
- MakeBinNohi
- Mov [Bp+20], Di ;save low word
- Mov [Bp+18], Dx ;save high word
- Loop MakeBinLoop ;loop back for next digit
-
- ;--- number successfully converted
-
- Clc
-
- MakeBinDone
- Pop Bp
- Pop Ds
- Pop Si
- Pop Di
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret
-
- ;--- nul string
-
- MakeBinNul
- Mov Word [Bp+20], 0000 ;error code
- Mov Word [Bp+18], 0000
- Stc
- Jmps MakeBinDone
-
- ;--- overflow
-
- MakeBinOver
- Mov Word [Bp+20], 0001 ;error code
- Mov Word [Bp+18], 0000
- Stc
- Jmps MakeBinDone
-
- ;--- illegal character
-
- MakeBinBad
- Mov Word [Bp+20], 0002 ;error code
- Mov Word [Bp+18], 0000
- Stc
- Jmps MakeBinDone
- Endp ;Make_Bin_P
-
- ;================================================
- ; Translate the 32-bit number into a decimal
- ; ASCII string. The low word of the number
- ; must be pushed onto the stack first. The
- ; local string address is returned on the stack.
-
- Make_Dec_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
- Cld ;clear direction
-
- Mov Ax, Cs
- Mov Ds, Ax
- Mov Es, Ax ;set data segments
-
- Mov Bx, 10 ;number base
- Sub Cx, Cx ;CX counts digits
- Mov Di, Offset MakeDecBuff ;number buffer location
- Mov Si, Di
- Inc Di
- Mov Bp, Sp ;pointer to value
-
- ;--- loop for each digit, at least one 0
-
- MakeDecLoop
- Mov Ax, [Bp+20] ;high word of value
- Sub Dx, Dx ;clear for divide
- Div Ax, Bx ;divide, DX gets remainder
- Mov [Bp+20], Ax ;save quotient (high word)
-
- Mov Ax, [Bp+22] ;low word of value
- Div Ax, Bx ;divide, DX gets remainder (the digit)
- Mov [Bp+22], Ax ;save quotient (low word)
-
- Add Dl, '0' ;make ASCII
- Mov Al, Dl
- Stosb ;store
- Inc Cx ;another digit
-
- Cmp Word [Bp+22], 0 ;check if low word zero
- Jne MakeDecLoop ;jump if not
- Cmp Word [Bp+20], 0 ;check if high word zero
- Jne MakeDecLoop ;jump if not
-
- ;--- done with number
-
- Mov [Si], Cl ;save length
- Shr Cx ;CX/2
- Jz MakeDecDone ;jump if nothing to switch
- Dec Di ;last digit
- Inc Si ;first digit
- Xchg Si, Di ;SI points to end, DI points to beginning
-
- ;--- reverse digits
-
- MakeDecRLoop
- Seg Es
- Mov Al, [Di] ;load front character
- Xchg Al, [Si] ;swap with end character
- Stosb ;store new front character
- Dec Si ;back up
- Loop MakeDecRLoop ;loop back for each digit
-
- ;--- finished
-
- MakeDecDone
- Mov Word [Bp+22], Offset MakeDecBuff ;save offset
- Mov [Bp+20], Ds ;save segment
-
- Clc
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax ;restore registers
- Ret
-
- ;--- data
-
- MakeDecBuff Label Byte ;string buffer
- Ds 11
- Endp ;Make_Dec_P
-
- ;================================================
- ; Get the string representing the present day.
- ; The day index (Sunday=0, etc.) must be in the
- ; low byte of the word pushed on the stack. The
- ; local string address is returned on the
- ; stack.
-
- Day_Str_P Proc Near
- Sub Sp, 2 ;room for return data
- Push Bx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Bx, [Bp+8]
- Mov [Bp+6], Bx ;move return address
-
- Mov Bx, Cs
- Mov Ds, Bx ;load data segment
- Mov Bl, [Bp+10] ;get day index
- Sub Bh, Bh ;clear high part of index
- Shl Bx ;times two (two bytes per entry)
- Add Bx, Offset DayStrList ;offset of string location
- Mov Bx, [Bx] ;get string location
-
- Mov [Bp+10], Bx ;save offset
- Mov [Bp+8], Ds ;save segment
-
- Pop Bp
- Pop Ds
- Pop Bx
- Ret
-
- ;--- table of day strings
-
- DayStrList Label Word
- Dw Offset DayStr01, Offset DayStr02, Offset DayStr03, Offset DayStr04
- Dw Offset DayStr05, Offset DayStr06, Offset DayStr07
-
- ;--- day strings
-
- DayStr01 Db 6,'Sunday'
- DayStr02 Db 6,'Monday'
- DayStr03 Db 7,'Tuesday'
- DayStr04 Db 9,'Wednesday'
- DayStr05 Db 8,'Thursday'
- DayStr06 Db 6,'Friday'
- DayStr07 Db 8,'Saturday'
- Endp ;Day_Str_P
-
- ;================================================
- ; Get the string representing the present
- ; month. The month index (January=0, etc.) must
- ; be in the low byte of the word pushed on the
- ; stack. The local string address is returned
- ; on the stack.
-
- Month_Str_P Proc Near
- Sub Sp, 2 ;room for return data
- Push Bx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Bx, [Bp+8]
- Mov [Bp+6], Bx ;move return address
-
- Mov Bx, Cs
- Mov Ds, Bx ;load data segment
- Mov Bl, [Bp+10] ;get day index
- Sub Bh, Bh ;clear high part of index
- Shl Bx ;times two (two bytes per entry)
- Add Bx, Offset MonthStrList ;offset of string location
- Mov Bx, [Bx] ;get string location
-
- Mov [Bp+10], Bx ;save offset
- Mov [Bp+8], Ds ;save segment
-
- Pop Bp
- Pop Ds
- Pop Bx
- Ret
-
- ;--- table of month strings
-
- MonthStrList Label Word
- Dw Offset MonthStr01, Offset MonthStr02, Offset MonthStr03
- Dw Offset MonthStr04, Offset MonthStr05, Offset MonthStr06
- Dw Offset MonthStr07, Offset MonthStr08, Offset MonthStr09
- Dw Offset MonthStr10, Offset MonthStr11, Offset MonthStr12
-
- ;--- month strings
-
- MonthStr01 Db 7,'January'
- MonthStr02 Db 8,'February'
- MonthStr03 Db 5,'March'
- MonthStr04 Db 5,'April'
- MonthStr05 Db 3,'May'
- MonthStr06 Db 4,'June'
- MonthStr07 Db 4,'July'
- MonthStr08 Db 6,'August'
- MonthStr09 Db 9,'September'
- MonthStr10 Db 7,'October'
- MonthStr11 Db 8,'November'
- MonthStr12 Db 8,'December'
- Endp ;Month_Str_P
-
- ;================================================
- ; Get the string representing the time the in
- ; XX:XX am/pm format (e.g. 3:27 pm). The hours
- ; must be in the high byte of the word on the
- ; stack and the minutes must be in the low
- ; byte. The local string address is returned on
- ; the stack.
-
- Time_Str_P Proc Near
- Sub Sp, 2 ;room for return data
- Push Ax
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Bx, [Bp+8]
- Mov [Bp+6], Bx ;move return address
-
- Mov Ax, Cs
- Mov Ds, Ax ;set segment registers
-
- Mov Ax, Offset TimeStrBuff ;storage
- Push Ax
- Push Ds
- Call Clear_Str_P ;initialize string
-
- ;--- hours
-
- Mov Al, [Bp+11] ;get hours
- Or Al, Al ;check if 12am to 12:59am
- Jnz TimeStrHour1 ;jump if not
- Mov Al, 12 ;set to 12
-
- TimeStrHour1
- Cmp Al, 13 ;check if next half
- Jb TimeStrHour2 ;jump if not
- Sub Al, 12 ;reset half
-
- TimeStrHour2
- Sub Ah, Ah
- Push Ax
- Sub Ax, Ax ;high word of number is zero
- Push Ax
- Call Make_Dec_P ;create number string
- Call Copy_Str_P ;copy string to buffer
-
- Mov Ah, ':' ;colon
- Mov Al, 1 ;count
- Push Ax
- Call Append_Chrs_P ;append character
-
- ;--- minutes
-
- Mov Al,[Bp+10] ;get minutes
- Sub Ah, Ah
- Push Ax
- Sub Ax, Ax ;high word of number is zero
- Push Ax
- Call Make_Dec_P ;create number string
- Mov Al, 2 ;string size
- Mov Ah, '0' ;justify character
- Push Ax
- Call Format_Rgt_P ;append string to buffer
-
- ;--- am/pm
-
- Mov Ax, Offset TimeStrPm
- Cmp Byte [Bp+11], 12 ;check after noon
- Jae TimeStrAmPm ;jump if so
- Mov Ax, Offset TimeStrAm
-
- TimeStrAmPm
- Push Ax
- Push Ds
- Call Append_Str_P ;append string
-
- ;--- set return data
-
- Pop Ax ;return segment
- Mov [Bp+8], Ax ;save
- Pop Ax ;return offset
- Mov [Bp+10], Ax ;save
-
- Pop Bp
- Pop Ds
- Pop Ax
- Ret
-
- ;--- data
-
- TimeStrPm Db 3,' pm'
- TimeStrAm Db 3,' am'
-
- TimeStrBuff Label Byte
- Db ?,'??:?? ??'
- Endp ;Time_Str_P
-
- ;================================================
- ; Translate string format into a name format
- ; (a sequence of characters terminated by byte
- ; 00). The local string address is returned on
- ; the stack.
-
- Make_Nam_P Proc Near
- Push Cx
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
-
- Mov Bp, Sp
- Mov Si, [Bp+16] ;get offset
- Mov Ds, [Bp+14] ;get segment
-
- Mov Cx, Cs
- Mov Es, Cx ;set local data segment
- Mov Di, Offset MakeNamBuff ;local buffer
- Mov Cl, [Si] ;length
- Sub Ch, Ch
- Inc Si ;skip length
- Rep
- Movsb ;copy string
-
- Seg Es
- Mov Byte [Di], 0 ;store terminating zero
- Mov Word [Bp+16], Offset MakeNamBuff ;save offset
- Mov [Bp+14], Es ;save segment
-
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Cx
- Clc
- Ret
-
- ;--- local storage
-
- MakeNamBuff Label Byte
- Ds 256 ;room for 255 bytes and 00
- Endp ;Make_Nam_P
-
- ;================================================
- ; Translate a name format string (a sequence of
- ; characters terminated by byte 00) into a normal
- ; string (a string of characters preceded by a byte
- ; containing its length). The local string address
- ; is returned on the stack.
-
- Make_Str_P Proc Near
- Push Ax
- Push Di
- Push Si
- Push Ds
- Push Es
- Push Bp ;save registers
-
- Mov Bp, Sp
- Mov Si, [Bp+16] ;get offset
- Mov Ds, [Bp+14] ;get segment
-
- Mov Ax, Cs
- Mov Es, Ax ;set local data segment
- Mov Di, Offset MakeStrBuff+1 ;local buffer, skip length byte
- Sub Ah, Ah ;initial byte count
-
- ;--- loop for each byte
-
- MakeStrLoop
- Lodsb ;load next byte
- Or Al, Al ;check if end of string
- Jz MakeStrFinish ;jump if so
-
- Inc Ah ;update count
- Jz MakeStrError ;jump if too big
- Stosb ;store byte
- Jmp MakeStrLoop ;loop back for next byte
-
- ;--- finished
-
- MakeStrFinish
- Clc
-
- MakeStrDone
- Mov Di, Offset MakeStrBuff ;local buffer
- Seg Es
- Mov [Di], Ah ;save string length
- Mov [Bp+16], Di ;save offset
- Mov [Bp+14], Es ;save segment
-
- Pop Bp
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Ax
- Clc
- Ret
-
- ;--- error, string too long
-
- MakeStrError
- Mov Ah, 255 ;max length
- Stc
- Jmps MakeStrDone
-
- ;--- local storage
-
- MakeStrBuff Label Byte
- Ds 256 ;room for 255 bytes and length
- Endp ;Make_Str_P
-
- ;================================================
- ; Return the status of the standard input device.
- ; ZF=1 if no characters waiting.
-
- Input_Sta_P Proc Near
- Push Ax
- Mov Ah, 0bh ;function number
- Int 21h ;execute
- Or Al, Al ;set ZF
- Pop Ax
- Ret
- Endp ;Input_Sta_P
-
- ;================================================
- ; Input a character from the standard input. AL
- ; returns the character. AX not preserved.
-
- Input_Chr_P Proc Near
- Mov Ah, 1 ;function number
- Int 21h ;execute
- Ret
- Endp ;Input_Chr_P
-
- ;================================================
- ; Input a character from the standard input
- ; without a screen echo. AL returns the
- ; character. AX not preserved.
-
- Input_Hid_P Proc Near
- Mov Ah, 8 ;function number
- Int 21h ;execute
- Ret
- Endp ;Input_Hid_P
-
- ;================================================
- ; Input a string from the user and move the cursor
- ; to the next line. The maximum input size (0 to
- ; 254) must be in the low byte of a word pushed on
- ; the stack. If the input length is too big the
- ; carry is set, otherwise the carry is cleared and
- ; the ZF will be set if the input length is zero.
- ; The string address is returned.
-
- Input_Str_P Proc Near
- Sub Sp, 2 ;allow for extra word of data
- Push Ax
- Push Bx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ax, Cs
- Mov Ds, Ax ;set data segment
-
- Mov Ax, [Bp+12]
- Mov [Bp+10], Ax ;fix return address
-
- Mov Al, [Bp+14] ;get max input length
- Mov Word [Bp+14], Offset InputStrBuff+1 ;set offset
- Mov Word [Bp+12], Ds ;set segment
-
- Inc Al ;account for CR
- Jz Badinput ;jump if too big (can only be up to 254)
- Mov InputStrBuff, Al ;save length
-
- Mov Ah, 0ah ;function
- Mov Dx, Offset InputStrBuff ;formatted buffer
- Int 21h ;execute
-
- Mov Dl, 10 ;linefeed
- Call Display_Chr_P ;display
-
- Mov Bl, InputStrBuff + 1 ;get input length
- Sub Bh, Bh ;clear upper byte
- Mov Byte [Bx+InputStrBuff+2], 0 ;store 00 on CR
- Or Bx, Bx ;set ZF
- Clc
-
- InputStrDone
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Bx
- Pop Ax
- Ret
-
- ;--- input was too big
-
- Badinput
- Mov Byte InputStrBuff + 1, 0 ;set zero input length
- Stc
- Jmps InputStrDone
-
- ;--- data
-
- InputStrBuff Label Byte
- Db ? ;maximum length
- Db ? ;input length
- Ds 255 ;storage for full string
- Endp ;Input_Str_P
-
- ;================================================
- ; Move the cursor to the upper left corner.
-
- Home_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset HomeCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- HomeCurCode Db 6,27,'[1;1H' ;control string
- Endp ;Home_Cur_P
-
- ;================================================
- ; Move the cursor left one column.
-
- Left_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset LeftCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- LeftCurCode Db 3,27,'[D' ;control string
- Endp ;Left_Cur_P
-
- ;================================================
- ; Move the cursor right one column.
-
- Right_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset RightCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- RightCurCode Db 3,27,'[C' ;control string
- Endp ;Right_Cur_P
-
- ;================================================
- ; Move the cursor up one row.
-
- Up_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset UpCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- UpCurCode Db 3,27,'[A' ;control string
- Endp ;Up_Cur_P
-
- ;================================================
- ; Move the cursor down one row.
-
- Down_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset DownCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- DownCurCode Db 3,27,'[B' ;control string
- Endp ;Down_Cur_P
-
- ;================================================
- ; Save the cursor positon.
-
- Save_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset SaveCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- SaveCurCode Db 3,27,'[s' ;control string
- Endp ;Save_Cur_P
-
- ;================================================
- ; Restore the cursor position.
-
- Restore_Cur_P Proc Near
- Push Ax
- Mov Ax, Offset RestoreCurCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- RestoreCurCode Db 3,27,'[u' ;control string
- Endp ;Restore_Cur_P
-
- ;================================================
- ; Move the cursor to a specified position. The
- ; column must be in the low byte of the word
- ; pushed on the stack and the row must be in
- ; the high byte. The upper left corner is 0,0.
- ; Will only calculate up to 99,99 (which should be
- ; large enough for most screens).
-
- Locate_Cur_P Proc Near
- Push Ax
- Push Bx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Ax, Cs
- Mov Ds, Ax
- Mov Bp, Sp
- Mov Bx, Offset LocateCurCode
- Mov Dl, 10 ;base number
- Mov Dh, '0' ;ascii conversion value
-
- Mov Al, [Bp+13] ;row
- Sub Ah, Ah
- Div Al, Dl ;get digits
-
- Add Al, Dh
- Add Ah, Dh ;make both ascii
- Mov [Bx+3], Al ;store tens digit
- Mov [Bx+4], Ah ;store ones digit
-
- Mov Al, [Bp+12] ;column
- Sub Ah, Ah
- Div Al, Dl ;get digits
-
- Add Al, Dh
- Add Ah, Dh ;make both ascii
- Mov [Bx+6], Al ;store tens digit
- Mov [Bx+7], Ah ;store ones digit
-
- Push Bx
- Push Ds
- Call Display_Str_P ;send string
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Bx
- Pop Ax
- Ret 2
- LocateCurCode Db 8,27,'[??;??H'
- Endp ;Locate_Cur_P
-
- ;================================================
- ; Set display attribute to normal.
-
- Normal_Atr_P Proc Near
- Push Ax
- Mov Ax, Offset NormalAtrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- NormalAtrCode Db 4,27,'[0m' ;control string
- Endp ;Normal_Atr_P
-
- ;================================================
- ; Set display attribute to bold.
-
- Bold_Atr_P Proc Near
- Push Ax
- Mov Ax, Offset BoldAtrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- BoldAtrCode Db 4,27,'[1m' ;control string
- Endp ;Bold_Atr_P
-
- ;================================================
- ; Set display attribute to underline.
-
- Underline_Atr_P Proc Near
- Push Ax
- Mov Ax, Offset UnderlineAtrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- UnderlineAtrCode Db 4,27,'[4m' ;control string
- Endp ;Underline_Atr_P
-
- ;================================================
- ; Set display attribute to blink.
-
- Blink_Atr_P Proc Near
- Push Ax
- Mov Ax, Offset BlinkAtrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- BlinkAtrCode Db 4,27,'[5m' ;control string
- Endp ;Blink_Atr_P
-
- ;================================================
- ; Set display attribute to reverse video.
-
- Reverse_Atr_P Proc Near
- Push Ax
- Mov Ax, Offset ReverseAtrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- ReverseAtrCode Db 4,27,'[7m' ;control string
- Endp ;Reverse_Atr_P
-
- ;================================================
- ; Clear the screen and home the cursor.
-
- Clear_Scr_P Proc Near
- Push Ax
- Mov Ax, Offset ClearScrCode
- Push Ax
- Push Cs
- Call Display_Str_P ;send string
- Pop Ax
- Ret
- ClearScrCode Db 4,27,'[2J' ;control string
- Endp ;Clear_Scr_P
-
- ;================================================
- ; Display the character in DL to the standard
- ; output.
-
- Display_Chr_P Proc Near
- Push Ax
- Mov Ah, 2 ;function number
- Int 21h ;execute
- Pop Ax
- Ret
- Endp ;Display_Chr_P
-
- ;================================================
- ; Sound the speaker.
-
- Sound_Bel_P Proc Near
- Push Dx
- Mov Dl, 7 ;BEL
- Call Display_Chr_P ;display
- Pop Dx
- Ret
- Endp ;Sound_Bel_P
-
- ;================================================
- ; Start a new display line.
-
- Line_P Proc Near
- Push Dx
- Mov Dl, 13 ;CR
- Call Display_Chr_P ;display
- Mov Dl, 10 ;LF
- Call Display_Chr_P ;display
- Pop Dx
- Ret
- Endp ;Line_P
-
- ;================================================
- ; Display the destination string to the
- ; standard output device.
-
- Display_Str_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 40h ;function number
- Mov Bx, [Bp+16] ;get offset
- Mov Ds, [Bp+14] ;get segment
- Mov Cl, [Bx] ;get length byte
- Sub Ch, Ch ;clear upper byte, CX=length
- Mov Dx, Bx
- Inc Dx ;start of string body
- Mov Bx, 1 ;standard output
- Int 21h ;execute
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret 4
- Endp ;Display_Str_P
-
- ;================================================
- ; Display the destination string to the
- ; standard output device and then move the
- ; cursor to the next line.
-
- Display_Lin_P Proc Near
- Push Ax
- Push Bp
- Sub Sp, 4
- Mov Bp, Sp
- Mov Ax, [Bp+12]
- Mov [Bp+2], Ax ;offset
- Mov Ax, [Bp+10]
- Mov [Bp], Ax ;segment
- Call Display_Str_P ;display string
- Call Line_P ;next line
- Pop Bp
- Pop Ax
- Ret 4
- Endp ;Display_Lin_P
-
- ;================================================
- ; Open a file for reading and writing. The name
- ; location must be on the stack. The file handle
- ; is returned on the stack. The name should be a
- ; byte 00 terminated string.
-
- Open_Fil_P Proc Near
- Push Ax
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Al, 00000010b ;read/write status
- Mov Ah, 3dh ;function number
- Mov Dx, [Bp+12] ;name offset
- Mov Ds, [Bp+10] ;name segment
- Int 21h ;execute
- Mov [Bp+12], Ax ;save handle
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Ax
- Ret 2
- Endp ;Open_Fil_P
-
- ;================================================
- ; Create or truncate a file for reading and
- ; writing. The name location must be on the stack.
- ; The file handle is returned on the stack. The
- ; name should be a byte 00 terminated string.
-
- Create_Fil_P Proc Near
- Push Ax
- Push Cx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 3ch ;function number
- Sub Cx, Cx ;normal attribute
- Mov Dx, [Bp+14] ;name offset
- Mov Ds, [Bp+12] ;name segment
- Int 21h ;execute
- Mov [Bp+14], Ax ;save handle
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Cx
- Pop Ax
- Ret 2
- Endp ;Create_Fil_P
-
- ;================================================
- ; Delete a file. The location of the name of the
- ; file must be passed on the stack. The name should
- ; be a byte 00 terminated string.
-
- Delete_Fil_P Proc Near
- Push Ax
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 41h ;function number
- Mov Dx, [Bp+12] ;name offset
- Mov Ds, [Bp+10] ;name segment
- Int 21h ;execute
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Ax
- Ret 4
- Endp
-
- ;================================================
- ; Read from a file. The handle, bytes to read,
- ; and buffer address (32 bit) must be pushed on
- ; the stack. The handle and bytes read are returned.
-
- Read_Fil_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 3fh ;function number
- Mov Bx, [Bp+20] ;handle
- Mov Cx, [Bp+18] ;bytes to write
- Mov Dx, [Bp+16] ;buffer offset
- Mov Ds, [Bp+14] ;buffer segment
- Int 21h ;execute
- Mov [Bp+18], Ax ;save bytes written
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret 4
- Endp ;Read_Fil_P
-
- ;================================================
- ; Write to a file. The handle, bytes to write,
- ; and buffer address (32 bit) must be pushed on
- ; the stack. The handle and bytes written are
- ; returned.
-
- Write_Fil_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Ds
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 40h ;function number
- Mov Bx, [Bp+20] ;handle
- Mov Cx, [Bp+18] ;bytes to write
- Mov Dx, [Bp+16] ;buffer offset
- Mov Ds, [Bp+14] ;buffer segment
- Int 21h ;execute
- Mov [Bp+18], Ax ;save bytes written
-
- Pop Bp
- Pop Ds
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret 4
- Endp ;Write_Fil_P
-
- ;================================================
- ; Seek an absolute location within a file. The
- ; handle, a 16 bit record size, and a 32 bit (low
- ; word first) record number must be passed on the
- ; stack. The handle is returned. Does not check
- ; for too large a seek.
-
- Seek_Fil_P Proc Near
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Bp
-
- Mov Bp, Sp
- Mov Bx, [Bp+16] ;record size
- Mov Ax, [Bp+12] ;high word
- Mul Ax, Bx ;multiply high word (error if carry)
- Mov Cx, Ax ;first part of high word
- Mov Ax, [Bp+14] ;low word high word of record number
- Mul Ax, Bx ;multiply low word
- Add Cx, Dx ;add in second part of high word (error if carry)
- Mov Dx, Ax ;final absolute offset in CX.DX
-
- Mov Bx, [Bp+18] ;handle
- Mov Ax, 4200h ;function number
- Int 21h ;execute
-
- Pop Bp
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret 6
- Endp ;Seek_Fil_P
-
- ;================================================
- ; Return the size of a file and move the read/
- ; write pointer to the end of the file. The handle
- ; and the (32 bit) size are returned. The high
- ; word of the size must be popped first.
-
- Size_Fil_P Proc Near
- Sub Sp, 4
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Bp
-
- Mov Bp, Sp
- Mov Ax, [Bp+14]
- Mov [Bp+10], Ax ;fix return address
-
- Mov Ax, 4202h ;function number
- Mov Bx, [Bp+16] ;handle
- Sub Cx, Cx
- Mov Dx, Cx ;move to offset from end 0000.0000
- Int 21h ;execute
-
- Mov [Bp+14], Ax ;low word
- Mov [Bp+12], Dx ;high word
-
- Pop Bp
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret
- Endp ;Size_Fil_P
-
- ;================================================
- ; Close a file. The file handle must be passed on
- ; the stack.
-
- Close_Fil_P Proc Near
- Push Ax
- Push Bx
- Push Bp
-
- Mov Bp, Sp
- Mov Ah, 3eh ;function number
- Mov Bx, [Bp+8] ;get file handle
- Int 21h ;execute
-
- Pop Bp
- Pop Bx
- Pop Ax
- Ret 2
- Endp
-
- ;================================================
- ; Return the number of bytes free on the disk.
- ; The drive number (0=default, 1=A, etc.) must be
- ; in the low byte of a word passed on the stack.
- ; The 32 bit number containing the free bytes is
- ; returned. Carry set if invalid drive.
-
- Free_Dsk_P Proc Near
- Sub Sp, 2
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Bp
-
- Mov Bp, Sp
- Mov Ax, [Bp+12]
- Mov [Bp+10], Ax ;fix return address
-
- Mov Ah, 36h ;function number
- Mov Dl, [Bp+14] ;drive code
- Int 21h ;execute
- Cmp Ax, -1 ;check if error
- Je FreeDskError ;jump if so
-
- Mul Ax, Bx ;get available clusters in DX:AX
- Mov Bx, Ax ;in DX:BX
- Mov Ax, Dx
- Mul Ax, Cx ;high word of bytes, if DX<>0 then error (too big)
- Xchg Ax, Bx ;save in BX
- Mul Ax, Cx ;low word of bytes
- Add Dx, Bx ;add both high words, if carry then error (too big)
-
- Mov [Bp+14], Ax ;save low word
- Mov [Bp+12], Dx ;save high word
- Clc
-
- FreeDskDone
- Pop Bp
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Ret
-
- ;--- invalid drive
-
- FreeDskError
- Mov Word [Bp+14], 0 ;save low word
- Mov Word [Bp+12], 0 ;save high word
- Stc
- Jmps FreeDskDone
- Endp ;Free_Dsk_P
-
- ;================================================
- ; Sound the speaker at a specified frequency for
- ; a specified amount of of time. The 16 bit
- ; frequency (in hertz -- minimum is 21) and the 16
- ; bit duration (in 1/100 seconds) must be passed
- ; on the stack. The duration is dependent upon the
- ; the speed and type of computer. If this routine
- ; is used on a faster computer, the number of nul
- ; loops executed for a single 1/100 second cycle
- ; should be adjusted accordingly. Though this
- ; routine directly manipulates the hardware, it
- ; does so in a fairly standardized manner, i.e.
- ; it should work on most compatibles.
-
- Sound_Spk_P Proc Near
- Push Ax
- Push Cx
- Push Dx
- Push Bp
- Mov Bp, Sp
-
- Mov Al, 0B6h
- Out 43h, Al ;timer mode
- Mov Dx, 14h
- Mov Ax, 4f38h ;divisor in DX.AX
- Mov Cx, [Bp+12] ;tone
- Cmp Cx, 15h ;check for minimum
- Jae SoundSpkOk ;jump if ok
- Mov Cx, 15h ;set to minimum (get divide overflow otherwise)
- SoundSpkOk
- Div Ax, Cx
- Out 42h, Al ;timer 2 low byte
- Mov Al, Ah
- Out 42h, Al ;timer 2 high byte
-
- In Al, 61h ;port B setting
- Mov Ah, Al
- Or Al, 3 ;turn on speaker
- Out 61h, Al
-
- Mov Dx, [Bp+10] ;duration
- SoundSpkWait
- Mov Cx, 2615 ;approx. 1/100 count (set for 4.77 MHz, 8088 computer)
- SoundSpkLoop
- Loop SoundSpkLoop ;loop for count
- Dec Dx ;reduce count
- Jnz SoundSpkWait ;loop back if more
-
- Mov Al,Ah
- Out 61h,Al ;turn off speaker
-
- Pop Bp
- Pop Dx
- Pop Cx
- Pop Ax
- Ret 4
- Endp
-
- Db Neg $Chksum ;library checksum
-
-