2000 ; PACKTOR Split screen RTTY/Packet/Amtor program ; Written entirely in A86 assembler ; by Mats Petersson SM5SXL ; ;************* FOSSIL version ************* DATA SEGMENT ORG 04000 pag db ? col db ? row db ? c_col db ? c_row db ? m_col db ? m_row db ? row_lim db ? win_y db ? c_flag db ? bkflag db ? vbufseg1 dw ? vbufseg2 dw ? vbufseg3 dw ? vbufseg4 dw ? cap_seg dw ? cap_offs dw ? f_hand dw ? f_hand2 dw ? color db ? DATA ENDS jmp main stackspace db 1024 dup 0 newstack: db 0 cap_flag db 0 bufw_flag db 0 asc_flag db 0 com_port dw 00H old_port dw 00H bps db 00000000xB parity db 00000000xB stopb db 00000000xB wordlen db 00000000xB com_ndx dw 0 bps_ndx dw 0 par_ndx dw 0 stop_ndx dw 0 word_ndx dw 0 scr_adr dd 0b800:00000 border: db 80*2 dup 020 ;Make border out of spaces b_len equ $-border stripe: db 79 dup 020 ;Make stripe out of spaces s_len equ $-stripe shadow: db 79 dup 223 shad_len equ $-shadow hdrtxt1: db ' P A C K T O R ' len1 equ $-hdrtxt1 hdrtxt2: db ' Amateur Radio Terminal Program v1.0 ' len2 equ $-hdrtxt2 time_str: db 'Time: ' time_len equ $-time_str fkprompt: db 'Input new value for function key: $' main: call fossil_chk ;CHECK FOR FOSSIL DRIVER mov sp,newstack ;New stack pointer mov ah,4aH ;Mshrink mov bx,65535/16 ;Bytes left for program int 21H mov ah,48H ;Malloc mov bx,65535/16 ;Number of 16-bytes paragraphs int 21H mov vbufseg1,ax ;Pointer to allocated segment mov ah,48H ;Malloc mov bx,65535/16 int 21H mov cap_seg,ax ;Pointer to allocated segment mov cap_offs,0 mov ah,0fH ;Return Video State int 10H mov pag,bh ;Save Active Page mov ah,05H ;Select Page mov al,pag int 10H push bp mov ah,06H ;Clear screen mov al,0 ;Number of lines blanked 0=Entire window mov bh,07H ;Attribute mov ch,0 ;row (y) of upper left corner mov cl,0 ;column (x) upper left corner mov dh,24 ;row (y) lower right corner mov dl,79 ;column(x) lower right corner int 10H pop bp mov ah,13H ;Show header border line 1 mov al,01H mov bh,pag ;Page number mov bl,17H ;Attribute (foreground & background color) mov cx,b_len ;Length of string mov dh,0 ;Row mov dl,0 ;Column mov bp,border ;Pointer to string int 10H mov dh,0 mov dl,79 call setcur mov ah,09H ;Endshadow1 mov al,220 mov bh,pag mov bl,07H mov cx,1 int 10H mov dh,1 mov dl,79 call setcur mov ah,09H ;Endshadow2 mov al,219 mov bh,pag mov bl,07H mov cx,1 int 10H mov ah,13H ;Show border undershadow mov al,01H mov bh,pag mov bl,07H mov cx,shad_len mov dh,2 mov dl,1 mov bp,shadow int 10H mov ah,13H ;Show middle stripe mov al,01H mov bh,pag mov bl,17H mov cx,s_len mov dh,18 mov dl,0 mov bp,stripe int 10H ;End shadow of border mov ah,09H mov al,220 mov bh,pag mov bl,07H mov cx,1 int 10H mov ah,13H ;Show stripe shadow mov al,01H mov bh,pag mov bl,07H mov cx,shad_len mov dh,19 mov dl,1 mov bp,shadow int 10H mov ah,13H ;Display border text 1 mov al,01H mov bh,pag ;Page number mov bl,1bH ;Attribute (foreground & background color) mov cx,len1 ;Length of string mov dh,0 ;Row mov dl,0 ;Column mov bp,hdrtxt1 ;Pointer to border text int 10H mov ah,13H ;Display border text 2 mov al,01H mov bh,pag ;Page number mov bl,1eH ;Attribute (foreground & background color) mov cx,len2 ;Length of string mov dh,1 ;Row mov dl,0 ;Column mov bp,hdrtxt2 ;Pointer to border text int 10H mov ah,13H ;Display "Time: " text mov al,01H mov bh,pag ;Page number mov bl,1eH ;Attribute (foreground & background color) mov cx,time_len ;Length of string mov dh,0 ;Row mov dl,67 ;Column mov bp,time_str ;Pointer to text int 10H ; call read_setup ; mov dx,com_port ;Install FOSSIL ; mov ah,04H ; int 14H ; mov ax,com_port ; mov old_port,ax ; call com_init ;Initialize com port mov c_col,0 mov c_row,20 mov m_col,0 mov m_row,3 start: mov dh,c_row ;Place cursor in output window mov dl,c_col ;while nothing happens call setcur mov ah,01H ; Test Keyboard input status int 16H jnz >l1 call modem_inp ; No char, test COM4 port instead call clock_rout ; Check time for update of time string jmp start l1: mov ah,00H ; Get next character in keyboard buffer int 16H push ax mov ah,12H ; Get extended shift status int 16H test ah,2 ; Alt key pressed? jz >l1 jmp altkeys l1: pop ax l2: cmp al,0D ; CR? jne >l3 xor c_flag,1 ; Set flag if CR comes from keyboard l3: call sendch ; (should be treated as CR/LF sequence) jmp start ;l1: cmp ah,75 ; Left arrow pressed? ; jne curr ; jmp curleft ;curr: cmp ah,77 ; Right arrow pressed? ; jne sendch ; jmp curright sendch: push ax mov dl,c_col mov dh,c_row mov col,dl ; Load output cursor values mov row,dh mov row_lim,24 mov win_y,20 call write ; Write character to screen mov dl,col ; Update output cursor mov dh,row mov c_col,dl mov c_row,dh mov c_flag,0 pop ax modem_out: mov dx,com_port ; Send character to Com port mov ah,01H int 14H call modem_inp ret quitprmpt: db 'Are you sure you want to Quit (y,N)? $' quit_string: db 'Thanks for using PACKTOR.',13,10,'$' quit: call getscr mov color,04fH call capwin mov dh,12 mov dl,20 call setcur mov ah,09H mov dx,quitprmpt int 21H l1: mov ah,01 int 16H jz l1 mov ah,00H int 16H ;Get character cmp ah,21 ;Scancode 21? (y/Y) je quit_ok call putscr jmp start quit_ok: mov ah,05H ; Select Page mov al,0 int 10H push bp mov ah,06H ; Clear screen mov al,0 ; Number of lines blanked 0=Entire window mov bh,07H ; Attribute (White on black) mov ch,0 ; row (y) of upper left corner mov cl,0 ; column (x) upper left corner mov dh,24 ; row (y) lower right corner mov dl,79 ; column(x) lower right corner int 10H pop bp push es mov es,vbufseg1 ;Mfree mov ah,49H int 21H mov es,cap_seg ;Mfree mov ah,49H int 21H pop es mov dx,03H ;Deinstall FOSSIL mov ah,05H int 14H mov dh,1 mov dl,0 call setcur mov ah,09H mov dx,quit_string int 21H mov ax,04C00 ; Exit with no error int 33 ; go back to the operating system modem_inp: mov dx,com_port ;get status of com port mov ah,03H int 14H test ah,1 ; Test if Data Ready jnz >l1 ret ; No,return l1: mov dx,com_port mov ah,02H ; read character int 14H tmp_write: ; Here starts the routine for tempbuf output test cap_flag,1 jz >l3 push es m 2000 ov es,cap_seg mov bp,cap_offs es mov b[bp],al inc bp mov cap_offs,bp pop es cmp cap_offs,65035 jnae >l3 test bufw_flag,1 jnz >l3 jmp buf_warn l3: mov row_lim,17 ; Set row limit and upper y value mov win_y,3 mov dl,m_col mov dh,m_row mov col,dl ; Load with input cursor values mov row,dh call write mov dl,col mov dh,row mov m_col,dl ; Update input cursor values mov m_row,dh ret write: cmp al,07FH jbe no_special cmp al,086H ;† je outchar cmp al,08fH ;¸ je outchar cmp al,084H ;„ je outchar cmp al,08EH ;ˇ je outchar cmp al,094H ;” je outchar cmp al,099H ;™ je outchar no_special: cmp al,32 jae outchar cmp al,0dH ;If CR, place cursor column 0 jne >l2 test c_flag,1 ;If CR comes from terminal,go 1 row down jz >l1 ;as if a CR/LF sequence together jmp incrow l1: jmp carriage l2: cmp al,0aH ;If LF, go down one row jne >l3 jmp incrow l3: cmp al,08H ;If BS, take appropriate action jne >l4 jmp bkspace cmp al,07H jne >l4 jmp outchar l4: ret outchar: mov dh,row mov dl,col call setcur mov ah,0aH ;Write character to screen mov bh,pag ;Page number mov cx,1 ;Number of characters int 10H inc col mov dh,row mov dl,col call setcur cmp col,80 je incrow ret bkspace: mov bkflag,1 curleft: dec col ;Column -1 cmp col,0 jge >l1 inc col ;If column<0 set column=0 l1: mov dh,row mov dl,col call setcur cmp bkflag,1 je blank ret blank: mov ah,0aH ;Blank out character mov al,020H ;With space mov bh,pag ;Page number mov cx,1 ;Number of characters int 10H mov bkflag,0 ret curright: inc col cmp col,80 jle >l1 dec col l1: mov dh,row mov dl,col call setcur ret incrow: inc row carriage: mov col,0 mov dh,row mov dl,col call setcur cmp dh,row_lim ;Cursor at row>24? jg scroll ;Yes, scroll window ret scroll: push bp mov ah,06H ;Clear screen mov al,1 ;Number of lines blanked 0=Entire window mov bh,07H ;Attribute mov ch,win_y ;row (y) of upper left corner (save border!) mov cl,0 ;column (x) upper left corner mov dh,row_lim ;row (y) lower right corner mov dl,79 ;column(x) lower right corner int 10H pop bp mov dl,row_lim mov row,dl ;Put back row to where it was before mov col,0 ;And column 0... mov dh,row mov dl,col call setcur ret altkeys: pop ax cmp ah,35 ; Alt-H scancode 0;35 jne >l1 jmp help l1: cmp ah,36 ; Alt-J scancode 0;36 jne >l2 jmp dosjump l2: cmp ah,22 ;Alt-U 0;22 jne >l3 jmp ascii_ul l3: cmp ah,50 ;Alt-M 0;50 jne >l4 jmp comm_set l4: cmp ah,38 ;Alt-L 0;38 jne >l5 jmp capture l5: cmp ah,33 ;Alt-F 0;33 jne >l6 jmp fkeys l6: cmp ah,45 ;Alt-X 0;45 jne >l7 jmp quit l7: cmp ah,31 ;Alt-S 0;31 jne >l8 jmp save_setup l8: jmp start helpscr: db ' ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ' hlplen: db ' ³ <<< HELP SCREEN >>> ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ Alt-M Set Comms Parameters ³ ' db ' ³ ³ ' db ' ³ Alt-L Capture buffer ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ Alt-F Define Function Keys ³ ' db ' ³ ³ ' db ' ³ Alt-U Send ASCII File Alt-S Save Setup ³ ' db ' ³ ³ ' db ' ³ Alt-J Jump to DOS Alt-X Quit Program ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ ESC Exit Help Screen ³ ' db ' ³ ³ ' db ' ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ' help: call getscr mov dh,2 mov dl,2 mov si,helpscr mov cx,21 hlplp: push cx mov ah,13H mov al,01H mov bh,pag mov bl,6eH mov cx,hlplen-helpscr mov bp,si int 10H inc dh add si,hlplen-helpscr pop cx loop hlplp l1: mov ah,01H ;Check keystroke buffer int 16H jz l1 mov ah,00 ;Get character int 16H cmp al,27 jne l1 call putscr jmp start ;*************************** Commands **************************** capbox: db ' ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ' caplen: db ' ³ ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ' combox :db ' ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ' comlen: db ' ³ COMMS PARAMETERS ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ³ (C)OM Port : ³ ' db ' ³ ³ ' db ' ³ (B)aud Rate : ³ ' db ' ³ ³ ' db ' ³ (P)arity : ³ ' db ' ³ ³ ' db ' ³ (S)top Bits : ³ ' db ' ³ ³ ' db ' ³ (W)ord Length : ³ ' db ' ³ ³ ' db ' ³ ³ ' db ' ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ' fkeys: dosjump: jmp start capprompt: db 'Name of Capture File: $' capfbuf: db 31,0 capfname: db 31 dup 0 capclosed: db 'CAPTURE FILE CLOSED$' striptext: db 'Capture On$' stripclr: db ' $' capture: xor cap_flag,1 test cap_flag,1 jz capclose call getscr mov color,05fH call capwin mov dh,12 mov dl,16 call setcur mov ah,09H mov dx,capprompt int 21H mov ah,0AH ;Buffered keyboard input mov dx,capfbuf int 21H mov bp,capfbuf mov dx,00000H mov dl,b[bp+1] mov si,dx cmp si,0 jne >l2 xor cap_flag,1 jmp cap_abort l2: mov b[bp+si+2],0 mov ah,03CH ;Create and open capture file mov cx,00000H ;Normal file mov dx,capfname int 21H mov f_hand,ax ;Save file handl 2000 e call putscr mov dh,18 mov dl,68 call setcur mov ah,09H ;Set color for text mov al,020H mov bh,pag mov bl,09e mov cx,10 int 10H mov ah,09H mov dx,striptext ;Show message on strip int 21H jmp start capclose: call getscr mov color,05fH call capwin mov dh,12 mov dl,29 call setcur mov ah,09H ;Output message mov dx,capclosed int 21H push ds mov ah,040H ;Write buffer to file mov bx,f_hand mov cx,cap_offs mov ds,cap_seg mov dx,00000 int 21H pop ds mov ah,03eH ;Close capture file mov bx,f_hand int 21H mov ah,00H int 16H cap_abort: mov bp,capfname mov cap_offs,00000H mov bufw_flag,0 call putscr mov dh,18 mov dl,68 call setcur mov ah,09H ;Set color for text mov al,020H mov bh,0 mov bl,01eH mov cx,1 int 10H mov ah,09H mov dx,stripclr ;Clear strip int 21H jmp start bufw_text1: db 'Warning! Only 1000 bytes left in buffer!$' bufw_text2: db ' Time to save...$' buf_warn: mov bufw_flag,1 call getscr call capwin mov dh,11 mov dl,20 call setcur mov ah,09H ;Write warning text mov dx,bufw_text1 int 21H mov dh,13 mov dl,20 call setcur mov ah,09H mov dx,bufw_text2 int 21H call delay call putscr jmp start ascii_text: db 'Upload ASCII filename: $' asc_errtext: db ' ERROR READING FILE$' ascfbuf: db 31,0 ascfname: db 31 dup 0 ascinbuf: db 0 del_counter dw 0 delay_flag db 0 ascii_ul: call getscr mov color,03fH call capwin mov dh,12 mov dl,16 call setcur mov ah,09H mov dx,ascii_text int 21H mov ah,0AH ;Buffered keyboard input mov dx,ascfbuf int 21H mov bp,ascfbuf mov dx,00000H mov dl,b[bp+1] mov si,dx cmp si,0 ;Abort if null string jne >l2 call putscr jmp ascii_abort l2: mov b[bp+si+2],0 ;Put a NULL at the end of string mov ax,03D00H ;Open ASCII text file mov dx,ascfname int 21H jc ascii_error call putscr mov asc_flag,1 mov f_hand2,ax ;Save file handle asc_to_com: test delay_flag,1 jz nodelay inc del_counter cmp del_counter,0fe0 jae >l1 call modem_inp jmp asc_to_com l1: mov delay_flag,0 nodelay: mov ah,03fH ;Read file mov bx,f_hand2 mov cx,1 ;1 byte to read mov dx,ascinbuf int 21H cmp ax,0 ;EOF? je asc_ready sub ax,ax mov si,ascinbuf mov al,b[si] ;Get ASCII character back buffer cmp al,0AH ;Delay at end of line jne >l1 mov del_counter,0 mov delay_flag,1 jmp asc_to_com l1: mov c_flag,1 call sendch jmp asc_to_com asc_ready: mov ah,03eH ;Close ASCII file mov bx,f_hand2 int 21H ascii_abort: mov asc_flag,0 mov c_flag,0 jmp start ascii_error: mov dh,12 mov dl,16 call setcur mov ah,09H mov dx,asc_errtext ;Error message int 21H call delay call putscr jmp ascii_abort capwin: mov dh,10 mov dl,12 mov si,capbox mov cx,5 caplp: push cx mov ah,13H mov al,01H mov bh,pag mov bl,color mov cx,caplen-capbox mov bp,si int 10H inc dh add si,caplen-capbox pop cx loop caplp ret ; 010 = 300 baud ; 011 = 600 '' ; 100 = 1200 '' ; 101 = 2400 '' ; 110 = 4800 '' ; 111 = 9600 '' ; 000 = 19200 '' (Replaces old 110 baud mask) ; 001 = 38400 '' (Replaces old 150 baud mask) ; The low order 5 bits can be implemented or not by the FOSSIL, but in all ; cases, if the low order bits of AL are 00011, the result should be that ; the communications device should be set to eight data bits, one stop bit ; and no parity. This setting is a MINIMUM REQUIREMENT of Fido, Opus and ; SEAdog. For purposes of completeness, here are the IBM PC "compatible" ; bit settings: ; Bits 4-3 define parity: 0 0 no parity ; 1 0 no parity ; 0 1 odd parity ; 1 1 even parity ; Bit 2 defines stop bits: 0 1 stop bit; ; 1 1.5 bits for 5-bit char; ; 2 for others ; Bits 1-0 character length: 0 0 5 bits ; 0 1 6 bits ; 1 0 7 bits ; 1 1 8 bits com_ptr: db 'COM1$' dw 0 db 'COM2$' dw 1 db 'COM3$' dw 2 db 'COM4$' dw 3 bps_ptr: db '300 $',01000000xB db '600 $',01100000xB db '1200 $',10000000xB db '2400 $',10100000xB db '4800 $',11000000xB db '9600 $',11100000xB db '19200$',00000000xB db '38400$',00100000xB par_ptr: db 'None$',00000000xB db 'Even$',00011000xB db 'Odd $',00001000xB stop_ptr:db '1$',00000000xB db '2$',00000100xB word_ptr:db '5$',00000000xB db '6$',00000001xB db '7$',00000010xB db '8$',00000011xB comm_set: call getscr mov dh,4 mov dl,12 mov si,combox mov cx,16 comlp: push cx mov ah,13H mov al,01H mov bh,pag mov bl,04eH mov cx,comlen-combox mov bp,si int 10H inc dh add si,comlen-combox pop cx loop comlp mov bp,com_ptr mov si,com_ndx add bp,si mov dh,8 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov bp,bps_ptr mov si,bps_ndx add bp,si mov dh,10 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov bp,par_ptr mov si,par_ndx add bp,si mov dh,12 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov bp,stop_ptr mov si,stop_ndx add bp,si mov dh,14 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov bp,word_ptr mov si,word_ndx add bp,si mov dh,16 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H comset_lp: mov ah,00H ;Read key int 16H cmp ah,46 ;Scancode for 'C' key jne bkey mov bp,com_ptr mov si,com_ndx inc si,7 cmp si,28 jne >l1 sub si,si l1: mov com_ndx,si add bp,si mov dh,8 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov ax,w[bp+5] mov com_port,ax jmp comset_lp bkey: cmp ah,48 ;'B' scancode jne pkey mov bp,bps_ptr mov si,bps_ndx inc si,7 cmp si,56 jne >l1 sub si,si l1: mov bps_ndx,si add bp,si mov dh,10 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov al,b[bp+6] mov bps,al jmp comset_lp pkey: cmp ah,25 ;'P' scancode jne skey mov bp,par_ptr mov si,par_ndx inc si,6 cmp si,18 jne >l1 sub si,si l1: mov par_ndx,si add bp,si mov dh,12 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov al,b[bp+5] mov parity,al jmp comset_lp skey: cmp ah,31 ;'S' scancode jne wkey mov bp,stop_ptr mov si,stop_ndx inc si,3 cmp si,6 jne >l1 sub si,si l1: mov stop_ndx,si add bp,si mov dh,14 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov al,b[bp+2] mov stopb,al jmp comset_lp wkey: cmp ah,17 ;'W' scancode jne esckey mov bp,word_ptr mov si,word_ndx inc si,3 cmp si,12 jne >l1 sub si,si l1: mov word_ndx,si add bp,si mov dh,16 mov dl,41 call setcur mov ah,09H mov dx,bp int 21H mov al,b[bp+2] mov wordlen,al jmp comset_lp esckey: cmp al,27 je >l1 jmp comset_lp l1: call com_init call putscr jmp start com_init: mov dx,old_port ;Begin with deinstalling FOSSIL mov ah,05H ;on the old com port i 952 nt 14H mov dx,com_port ;And install FOSSIL on the new one mov ah,04H int 14H mov ax,com_port ;Save port for later reference mov old_port,ax sub ax,ax or al,bps or al,parity or al,stopb or al,wordlen mov ah,00H ;Initialize COM4 to 9600,N,8,1 mov dx,com_port int 14H ret save_setup: ;com_port dw 0 ;com_ndx dw 0 ;bps_ndx dw 0 ;par_ndx dw 0 ;stop_ndx dw 0 ;word_ndx dw 0 delay: mov cx,-2 delay1: push cx mov cx,020 delay2: loop delay2 pop cx loop delay1 ret tmval_str: db 2 dup 0,':',2 dup 0,'$' old_min db 0ff clock_rout: mov ah,02H ;Read real time clock time int 1aH cmp cl,old_min ;Minutes changed? jne >l1 ret ;No, return l1: mov old_min,cl mov bp,tmval_str mov si,0 mov bl,ch call calc mov bl,cl call calc jmp out_time ;Yes, update time string calc: mov al,bl shr al,4 ;We want the high nibble... and al,0f add al,030 mov b[bp+si],al ;first character inc si mov al,bl and al,0f add al,030 mov b[bp+si],al ;second character inc si inc si ;skip over the ':' ret out_time: mov dh,0 ;Set cursor mov dl,73 call setcur mov ah,09H ;Set color for text mov al,020H mov bh,0 mov bl,01eH mov cx,5 int 10H mov ah,09H mov dx,tmval_str int 21H ret db 'GETSCREEN' getscr: push es push ds mov es,vbufseg1 mov di,0 lds si,scr_adr mov cx,36000 getlp: movsb loop getlp pop ds pop es ret putscr: push es push ds les di,scr_adr mov ds,vbufseg1 mov si,0 mov cx,36000 putlp: movsb loop putlp pop ds pop es ret setcur: mov ah,02H mov bh,0 int 10H ret bios_vecadr dd 0000:0050 no_fossil: db 13,10,'No FOSSIL driver present! Aborted...',13,10,'$' fossil_chk: push es les si,bios_vecadr mov di,si es mov si,w[di] es mov es,w[di+2] es cmp w[si+6],01954H ;FOSSIL driver installed? jne >l1 ;No,abort program pop es ret l1: mov ah,09H mov dx,no_fossil ;Warning message int 21H call delay mov ax,04c00 int 21H . 0