Category : Databases and related files
Archive   : ZUPSBA.ZIP
Filename : ZUPSBA.ASM

 
Output of file : ZUPSBA.ASM contained in archive : ZUPSBA.ZIP
;--------------------------------------------------------------------------;
; UPS-ZIP ;
;Program to convert a US Postal Service zip code to UPS 'zone' code ;
;--------------------------------------------------------------------------;

.MODEL small
.STACK 200h
.DATA
;-----------

;MESSAGES
progname_message DB 'ZIP to UPS','$'
descrip_message DB 'Converts U.S. Mail zipcode to UPS zone','$'
descrip2_message DB '[valid for sender in Baltimore, MD area]','$'
pd1_message DB '[c] 1991','$'
id1_message DB 'by','$'
id2_message DB 'M. Cooper','$'
id3_message DB '3138 Foster Ave.','$'
id4_message DB 'Baltimore, MD 21224-3934','$'
continue_message DB 'Press a key to continue ...','$'
zipcode_message DB 'Enter first three digits of zipcode ','$'
error_message DB 'INPUT ERROR [must be 3 digits, ea. 0 - 9].','$'
response_message DB 'The UPS zone number is ','$'
invalid_message DB 'Invalid zip code!','$'
do_again_message DB 'Do you want to enter another zipcode {y/n} ? ','$'

error_flag DB 0 ;flags error if zipcode invalid
error_flag_z DB 1 ;flags error if zone invalid (=0)
repeat_flag DB ? ;flag set if repeat for another try

input_buffer DB 4 ;tell DOS to accept only 3 bytes [4th is CR]
DB 0 ;DOS reports how many bytes actually input
DB 4 dup ('*') ;input stored here (in first 3 bytes)

buffer2 DB 2 ;accept 1 byte ( 'y' or 'n') [2nd is CR]
DB 0 ;DOS reports how many bytes input
DB 2 dup ('#') ;input here (1st byte)

temp DW 0 ;temporary register for int. mult. results
index DW 0 ;index storage
cursor_ptr DW 0450h ;cursor location

set EQU 1 ;flag setting
;-----------------data & characters for box-------------------------
start EQU 0000
character EQU 007c4h
vidram_seg EQU 0b000h
width_ EQU 78 ;width of box
height EQU 24 ;height of box
vertical_bar EQU 07b3h
horizontal_bar EQU 07c4h
upper_left EQU 07dah
upper_right EQU 07bfh
lower_left EQU 07c0h
lower_right EQU 07d9h
one_row EQU 0a0h

;--------------------------------------TABLE-------------------------------;
table DB 4 dup (0) ;000 - 003 invalid
DB 2 dup (3) ;004 - 005
DB 4 dup (0) ;006 - 009 invalid
DB 4 dup (3) ;010 - 013
DB 33 dup (4) ;014 - 046
DB 5 ;047
DB 4 dup (4) ;048 - 051
DB 2 dup (3) ;052 - 053
DB 6 dup (4) ;054 - 059
DB 10 dup (3) ;060 - 069
DB 20 dup (2) ;070 - 089
DB 10 dup (0) ;090 - 099 invalid

DB 5 dup (2) ;100 - 104
DB 5 dup (3) ;105 - 109
DB 4 dup (2) ;110 - 113
DB 2 dup (3) ;114 - 115
DB 2 ;116
DB 12 dup (3) ;117 - 128
DB 4 ;129
DB 24 dup (3) ;130 - 153
DB 2 dup (2) ;154 - 155
DB 3 ;156
DB 2 ;157
DB 3 ;158
DB 2 ;159
DB 6 dup (3) ;160 - 165
DB 2 ;166
DB 3 ;167
DB 2 ;168
DB 3 ;169
DB 18 dup (2) ;170 - 187
DB 3 ;188
DB 11 dup (2) ;189 -199

DB 33 dup (2) ;200 - 232
DB 5 dup (3) ;233 - 237
DB 2 dup (2) ;238 - 239
DB 2 dup (3) ;240 - 241
DB 4 ;242
DB 3 ;243
DB 2 ;244
DB 9 dup (3) ;245 - 253
DB 2 ;254
DB 10 dup (3) ;255 - 264
DB 2 ;265
DB 3 ;266
DB 2 dup (2) ;267 - 268
DB 0 ;269 ?
DB 10 dup (3) ;270 - 279
DB 3 dup (4) ;280 - 282
DB 3 ;283
DB 4 ;284
DB 3 ;285
DB 14 dup (4) ;286 - 299

DB 15 dup (4) ;300 - 314
DB 25 dup (5) ;315 - 339
DB 2 dup (0) ;340 - 341
DB 28 dup (5) ;342 - 369
DB 5 dup (4) ;370 - 374
DB 5 ;375
DB 4 dup (4) ;376 - 379
DB 5 dup (5) ;380 - 384
DB 4 ;385
DB 12 dup (5) ;386 - 397
DB 0 ;398 ?
DB 4 ;399

DB 19 dup (4) ;400 - 418
DB 0 ;419 ?
DB 5 ;420
DB 16 dup (4) ;421 - 436
DB 11 dup (3) ;437 - 447
DB 9 dup (4) ;448 - 456
DB 3 ;457
DB 40 dup (4) ;458 - 497
DB 2 dup (5) ;498 - 499

DB 10 dup (5) ;500 - 509
DB 3 dup (6) ;510 - 512
DB 49 dup (5) ;513 - 561
DB 6 ;562
DB 2 dup (5) ;563 - 564
DB 23 dup (6) ;565 - 587
DB 8 dup (7) ;588 - 595
DB 4 dup (8) ;596 - 599

DB 10 dup (4) ;600 - 609
DB 8 dup (5) ;610 - 617
DB 2 dup (4) ;618 - 619
DB 44 dup (5) ;620 - 663
DB 3 dup (6) ;664 - 666
DB 5 ;667
DB 26 dup (6) ;668 -693
DB 6 dup (0) ;694 - 699 ?

DB 3 dup (5) ;700 - 702
DB 6 ;703
DB 5 ;704
DB 7 dup (6) ;705 - 711
DB 5 ;712
DB 2 dup (6) ;713 - 714
DB 0 ;715 ?
DB 14 dup (5) ;716 - 729
DB 19 dup (6) ;730 - 748
DB 5 ;749
DB 19 dup (6) ;750 - 768
DB 7 ;769
DB 15 dup (6) ;770 - 784
DB 7 ;785
DB 2 dup (6) ;786 -787
DB 7 ;788
DB 4 dup (6) ;789 - 792
DB 2 dup (7) ;793 - 794
DB 2 dup (6) ;795 - 796
DB 3 dup (7) ;797 - 799

DB 32 dup (7) ;800 - 831
DB 13 dup (8) ;832 - 844
DB 7 ;845
DB 19 dup (8) ;846 - 864
DB 21 dup (7) ;865 - 885
DB 3 dup (0) ;886 - 888
DB 11 dup (8) ;889 - 899

DB 62 dup (8) ;900 - 961
DB 8 dup (0) ;962 - 969
DB 17 dup (8) ;970 - 986
DB 0 ;987
DB 7 dup (8) ;988 - 994
DB 5 dup (0) ;995 - 999


;-------------------------------------------------------------------------
line_feed EQU 0ah
cr EQU 0dh ;carriage return

;equates for clear-screen subroutine
length_ EQU 2000
char EQU 00720h

.CODE

BEGIN:

; initialize variables & save registers
save_registers: push ax
push bx
push cx
push dx
push si
push di
push ds
push es

;---------------------------------------------------------------------------

MAIN: ;main routine [calls functions]

initialize_ds: mov ax,@data
mov ds,ax

displays: call clear_screen ;wipe the screen
call draw_box ;format it
call continue ;to work
main1: call get_zipcode ;user input
call cvt_zc_to_index ;convert zip code to index
call lookup_zone ;get zone from data
call do_again ;does user want to repeat?
;---------------------------------
AGAIN: ;if da capo
call clear_screen
mov al,repeat_flag
cmp al,set ;is it or isn't it?
je main1 ;do it!

EXIT: ;restore registers & return to DOS [home again]
restore_registers: pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
back_to_DOS: mov ah,4ch
int 21h

;----------------------------SUBROUTINES-----------------------------------;

get_zipcode: ;Input zip code
;and checks if input is valid

ask_for_input: lea dx,zipcode_message
call display_string

get_input: lea dx,input_buffer ;where input is put in
mov ah,0ah ;Buffered kbd. input function
int 021h ;of DOS

;------
check_input: ;checks whether user inputs valid digits (0 - 9)

lea bx,input_buffer + 2 ;address of 1st digit
mov cx,3 ;3 digits to check
get_digit: mov al,[bx]
call check_digit
inc bx ;next digit
loop get_digit
if_error: mov al,error_flag
cmp al,0 ;is error_flag set?
jz end_of_input ;all hunky dory
mov error_flag,0 ;reset the flag
call error ;tell the turkey he done wrong

end_of_input: ret
;------------------
check_digit: ;if ea. input digit is o.k. (0 - 9)

cmp al,'0' ;check lower limit first
jl set_error_flag
cmp al,'9' ;check upper limit
jg set_error_flag
jmp SHORT end_of_check
set_error_flag: ;uh oh! something is wrong.
inc error_flag

end_of_check: ret

;--------------------------------------------------------------------------;
cvt_zc_to_index: ;converts zip code input to index for (lookup) table

save1: push ax ;save registers used
push bx

lea bx,input_buffer ;input zipcodes
hundreds: mov al,[bx + 2] ;fetch hundreds digit
call cvt_to_bin ;convert to number
xor ah,ah ;convert to word
call multiply_x_10 ;times 10 (decimal)
call multiply_x_10 ;= times 100 (decimal)
mov index,ax ;store in index

tens: mov al,[bx+3] ;fetch tens digit
call cvt_to_bin ;convert to number
xor ah,ah
call multiply_x_10 ;X10 only
add index,ax ;update index

ones: mov al,[bx+4] ;fetch ones digit
call cvt_to_bin
xor ah,ah
add index,ax

restore1: pop bx
pop ax
ret
;--------------------------------------------------------------------------;
lookup_zone: ;takes value in "index" and looks up ups zone in "table".

lea bx,table ;beginning of table
mov si,index ;where in table
mov dl,[bx + si] ;fetch it
call linefeed

checkzone: mov error_flag_z,1 ;clear
call check_zone
mov al,error_flag_z
cmp al,0
jz finis
call cvt_char ;change to ASCII char
respond: push dx
lea dx,response_message
call display_string
pop dx
answer: call display_char
finis: ret
;--------------------------------------------------------------------------;
check_zone: ;checks if valid zone
cmp dl,0 ;zero marks an invalid zone
jnz retrn
invalid_zone: mov error_flag_z,dl ;flag the error
lea dx,invalid_message ;tell about it
call display_string

retrn: ret
;--------------------------------------------------------------------------;
cvt_char: ;changes binary to ASCII digit (for display)
;entry:binary char in DL exit:ASCII char in DL

add dl,'0'
ret
;--------------------------------------------------------------------------;

cvt_to_bin: ;converts contents of AL to digit [0 - 9] in binary
;and returns it in AL

sub AL,'0'
ret
;--------------------------------------------------------------------------;
error: ;displays error message & loops back to input
;for a second try

lf: call linefeed ;down to next line
print_error_msg: lea dx,error_message
call display_string
reset_flag: mov error_flag,0
try_again: call linefeed ;2 blank lines
call linefeed ;before next try
call get_zipcode
ret
;---------------------------------------------------------------------------;
linefeed: ;creates LINEFEED
push dx ;save
mov dl,line_feed
call display_char
mov dl,cr
call display_char ;move to beginning of line
pop dx
ret
;---------------------------------------------------------------------------;
display_char: ;displays single character

mov ah,2 ;function #2
int 021h ;of DOS
ret
;--------------------------------------------------------------------------;
display_string: ;displays string pointed to by DX

mov ah,09 ;function #9
int 021h ;of DOS
ret
;--------------------------------------------------------------------------
multiply_x_10: ;multiplies # passed in AX x 10 and returns result in AX

shl ax,1 ;multiply x 2
mov temp,ax ;store intermediate result
shl ax,1 ;x4
shl ax,1 ;x8
add temp,ax ;x8 + x2 = x10
mov ax,temp
mov temp,0 ;clear temp
ret

;-------------------------------------------------------------------------;
; Clear screen subroutine ;
;-------------------------------------------------------------------------;
clear_screen:

save_reg: push ax
push cx
push dx
push es
push di
initialize: mov di,start ;setup for block move
mov cx,length_
mov ax,vidram_seg
mov es,ax
draw: mov ax,char
rep stosw
home_cursor: xor dx,dx ;setup [cursor to upper rt. hand cor.]
call cursor_pos
restore_reg: pop di
pop es
pop dx
pop cx
pop ax
back_to: ret
;----------------------------------------------------------------------------
;routine to ask if user wants to try another go-round

do_again:

clear_flag: mov repeat_flag,0

skip_2_lines: call linefeed
call linefeed

ask_if_again: lea dx,do_again_message
call display_string

get_input2: lea dx,buffer2 ;where 'y' or 'n' to be stored
mov ah,0ah ;buffered kbd. input function
int 021h ;of DOS

if_again: lea bx,buffer2 ;here is yea or nay
mov al,[bx + 2] ;2 after beginning of buffer
if_yes: cmp al,'y'
je set_repeat_flag ;set flag for repeat
cmp al,'Y'
jne loony_tunes ;not again!


set_repeat_flag:
mov repeat_flag,set



loony_tunes: ret

;-------------------------------------------------------------------------;
;Subroutine to draw a full-screen box ;
;-------------------------------------------------------------------------;
draw_box:

box_save: push ax
push cx
push es
push di
mov di,start
mov ax,vidram_seg
mov es,ax

draw_:

upperleft: mov ax,upper_left
mov es:[di],ax
topbar: mov ax,horizontal_bar
mov cx,width_
inc di
inc di
rep stosw
upperright: mov ax,upper_right
mov es:[di],ax
rtvertical: mov ax,vertical_bar
mov cx,height
drawvert: add di,one_row
mov es:[di],ax
loop drawvert
lowerright: mov ax,lower_right
mov es:[di],ax
bottombar: mov ax,horizontal_bar
mov cx,width_
dec di
dec di
std
rep stosw
cld
lowerleft: mov ax,lower_left
mov es:[di],ax
leftvertical: mov ax,vertical_bar
mov cx,height-1
drawvertl: sub di,one_row
mov es:[di],ax
loop drawvertl

box_restore: pop di
pop es
pop cx
pop ax
box_exit: ret
;---------------------------------------------------------------------------
continue: ;displays messages & asks for keystroke to continue

continue_save: push ax
push bx
push cx
push dx

;----------------------MESSAGES----------------------------;
_message_display:

DISPLAY_MESSAGE MACRO ROW,COLUMN,MESSAGE
mov dh,ROW
mov dl,COLUMN
call cursor_pos

lea dx,MESSAGE
call display_string
ENDM

;-----------------------------------------------------------;
DISPLAY_MESSAGE 2,34,progname_message ;name of program

DISPLAY_MESSAGE 5,21,descrip_message
DISPLAY_MESSAGE 6,20,descrip2_message
DISPLAY_MESSAGE 10,36,pd1_message
DISPLAY_MESSAGE 12,40,id1_message
DISPLAY_MESSAGE 14,36,id2_message
DISPLAY_MESSAGE 15,33,id3_message
DISPLAY_MESSAGE 16,29,id4_message

DISPLAY_MESSAGE 23,26,continue_message ;press a key to continue message
;-----------------------------

press_key: call keyin ;wait for key press

cls_: call clear_screen

continue_rest: pop dx
pop cx
pop bx
pop ax

c_end: ret
;--------------------------------------------------------------------------;
;KEYIN Keyboard input without echo ;
;--------------------------------------------------------------------------;
keyin: ;
push ax
mov ah,08h ;function #8
int 021h ;of DOS
pop ax

ret
;--------------------------------------------------------------------------;
; set cursor position [DH,DL = row, column] ;
;--------------------------------------------------------------------------;
cursor_pos:
xor bh,bh ;page 0
mov ah,02h ;function #2
int 010h ;of BIOS
ret
;--------------------------------------------------------------------------
END BEGIN







  3 Responses to “Category : Databases and related files
Archive   : ZUPSBA.ZIP
Filename : ZUPSBA.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/