     1                                  ; Retro UNIX 386 v1 Terminal Program (DOS version)
     2                                  ; (Standalone DOS program)
     3                                  ; by Erdogan TAN
     4                                  ;
     5                                  ; Last Update: 23/11/2015	
     6                                  ;
     7                                  ; serial6.s - 23/11/2015
     8                                  ; serial5.s - 10/11/2015 NASM 2.11 (buffered read)
     9                                  ;
    10                                  ; SERIAL4.ASM - 26/10/2015 (Retro UNIX 386 v1 - Kernel v0.2.0.15)
    11                                  ; SERIAL1.ASM (Retro UNIX 8086 v1)
    12                                  ; 08/07/2014, 23/07/2013, 27/07/2014 
    13                                  ; (06/07/2014, 05/07/2014, 04/07/2014, 03/07/2014)
    14                                  
    15                                  ; Assembler: NASM 2.11 
    16                                  
    17                                  [BITS 16]
    18                                  
    19                                  		[ORG 100h]
    20                                  
    21                                  		; 10/11/2015
    22                                  		; clear bss section
    23 00000000 B9[2406]                		mov	cx, bss_end
    24 00000003 BF[1004]                		mov	di, bss_start
    25 00000006 31C0                    		xor	ax, ax
    26 00000008 29F9                    		sub	cx, di
    27 0000000A D1E9                    		shr	cx, 1
    28 0000000C F3AB                    		rep	stosw
    29                                  		;
    30 0000000E B80006                  		mov 	ax, 0600h  ; Scroll up, clear (AL=0)
    31 00000011 B707                    		mov	bh, 07h    ; Black backround (0), 
    32                                  				   ; Light gray foreground (7)
    33                                  		;sub	cx, cx     ; Left-Upper column, row
    34 00000013 BA4F18                  		mov	dx, 184Fh  ; Righ-Lower column, row
    35 00000016 CD10                    		int 	10h			 
    36                                  		;
    37 00000018 B402                    		mov	ah, 2	   ; Set cursor position 	
    38 0000001A 31D2                    		xor	dx, dx	   ; Row 0 (DH), Column 0 (DL)	
    39 0000001C 30FF                    		xor	bh, bh ; 0
    40 0000001E CD10                    		int 	10h
    41                                  		;
    42 00000020 BE[F302]                		mov	si, StartMsg
    43 00000023 B307                    		mov	bl, 7
    44 00000025 E84102                  		call	proc_printmsg
    45                                  		;
    46 00000028 31C0                    		xor 	ax, ax
    47 0000002A 8ED8                    		mov	ds, ax
    48 0000002C BE6C00                  		mov	si, 27*4 
    49                                  				   ; INT 1Bh vector
    50 0000002F BF[1204]                		mov	di, old_ctrlbrk
    51 00000032 A5                                      movsw              ; Save the old ctrl+brk interrupt 
    52 00000033 A5                                      movsw
    53                                  		; 06/11/2015
    54                                  		;mov	si, 28*4 
    55                                  				   ; INT 1Ch vector
    56                                  		;mov	di, old_timer
    57 00000034 A5                                      movsw              ; Save the old timer interrupt 
    58 00000035 A5                                      movsw
    59                                  		;
    60 00000036 0E                                      push    cs
    61 00000037 1F                      		pop	ds
    62 00000038 FA                      		cli	; 06/11/2215
    63 00000039 8EC0                    		mov	es, ax
    64 0000003B B8[5902]                		mov	ax, ctrlbrk
    65 0000003E BF6C00                  		mov	di, 27*4   ; INT 1Bh vector - offset
    66 00000041 AB                      		stosw		
    67 00000042 8CC8                    		mov	ax, cs
    68 00000044 AB                      		stosw		   ; INT 1Bh vector - segment
    69                                  
    70                                  		; 06/11/2015
    71                                  		; INT 1Ch periodic timer interrupt (18.2 times per second)
    72                                  		;mov	di, 28*4   ; INT 1Ch vector - offset
    73                                  		;cli	; 06/11/2015
    74 00000045 B8[5F02]                		mov 	ax, _timer
    75 00000048 AB                      		stosw
    76 00000049 8CC8                      		mov	ax, cs
    77 0000004B AB                      		stosw		   ; INT 1Ch vector - segment
    78                                  
    79 0000004C 8EC0                    		mov	es, ax
    80 0000004E FB                      		sti	; 06/11/2015
    81                                  s0:
    82 0000004F 30E4                    		xor	ah, ah
    83 00000051 CD16                    		int 	16h
    84                                  		;
    85 00000053 3C31                    		cmp	al, '1'
    86 00000055 7426                    		je	short s1
    87 00000057 3C32                    		cmp	al, '2'
    88 00000059 7408                    		je	short _0
    89                                  		;
    90 0000005B B007                    		mov	al, 07h	   ; BEEP !
    91 0000005D B40E                    		mov	ah, 0Eh
    92 0000005F CD10                    		int	10h
    93 00000061 EBEC                    		jmp	short s0
    94                                  _0:
    95 00000063 BE[0504]                		mov	si, _3F8h + 1
    96 00000066 FE0C                    		dec 	byte [SI]	; 2F8h
    97 00000068 83C602                  		add	si, 2
    98 0000006B FE0C                    		dec 	byte [SI]	; 2F9h
    99                                  		; 28/10/2015
   100                                  		;add	si, 2
   101                                  		;dec 	byte [SI]	; 2FAh
   102 0000006D 83C602                  		add	si, 2
   103 00000070 FE0C                    		dec 	byte [SI]	; 2FCh
   104 00000072 83C602                  		add	si, 2
   105 00000075 FE0C                    		dec 	byte [SI]	; 2FDh
   106                                  		;add	si, 2
   107                                  		;dec 	byte [SI]	; 2FEh
   108                                  		;
   109 00000077 BE[0204]                		mov	si, _EFh
   110 0000007A C604F7                  		mov 	byte [SI], 0F7h	
   111                                  s1:
   112 0000007D 2C31                    		sub	al, '1'
   113 0000007F A2[1004]                		mov	byte [port], al
   114                                  		;
   115 00000082 BE[8E03]                		mov     si, ComSMsg
   116 00000085 004404                                  add     byte [SI+4], al
   117                                  		;mov	bx, 7
   118 00000088 E8DE01                  		call	proc_printmsg
   119                                  		;
   120                                  		; 26/10/2015
   121 0000008B E8E701                  		call	set_spcp ; Set communication parameters
   122 0000008E 7309                    		jnc	short s2
   123 00000090 BE[DA03]                                mov     si, ErrMsg
   124                                  		;mov	bx, 7
   125 00000093 E8D301                  		call	proc_printmsg
   126 00000096 E9D600                  		jmp	_exit
   127                                  s2:
   128                                  		; 06/11/2015
   129 00000099 8A16[1004]              		mov	dl, byte [port]
   130                                  				   ; hook serial port interrupt
   131 0000009D 31C0                    		xor	ax, ax ; 0
   132 0000009F 8ED8                    		mov 	ds, ax	   ; IVT base
   133                                  
   134 000000A1 BE2C00                  		mov	si, 0Bh*4  ; Port 1 (COM2)
   135 000000A4 20D2                    		and	dl, dl     ; Port 0 (COM1) ?
   136 000000A6 7503                    		jnz	short s3
   137 000000A8 83C604                  		add	si, 4	   ; 0Ch*4 (COM1)
   138                                  s3:
   139 000000AB 56                      		push	si
   140 000000AC BF[1A04]                                mov     di, old_serial
   141 000000AF A5                                      movsw              ; Save the old serial port interrupt   
   142 000000B0 A5                                      movsw
   143                                          	;
   144 000000B1 0E                      		push	cs
   145 000000B2 1F                      		pop	ds
   146 000000B3 8EC0                                    mov     es, ax     ; 0
   147 000000B5 5F                      		pop	di
   148                                  		;
   149 000000B6 FA                      		cli
   150 000000B7 B8[EC01]                		mov 	ax, serial  ; serial port interrupt handler
   151 000000BA AB                      		stosw		   ; INT 0Ch (0Bh) vector -   
   152 000000BB 8CC8                    		mov	ax, cs
   153 000000BD AB                      		stosw		   ; INT 0Ch (0Bh) vector - segment	
   154                                  		;mov	es, ax
   155 000000BE FB                      		sti              
   156                                  		;
   157 000000BF BE[A203]                		mov     si, AnyKeyMsg
   158 000000C2 E8A401                  		call	proc_printmsg
   159                                  		;
   160 000000C5 30E4                    		xor	ah, ah
   161 000000C7 CD16                    		int 	16h
   162                                  		;
   163 000000C9 3C1B                    		cmp	al, 1Bh    ; ESC key
   164 000000CB 0F84B700                                je      _return 
   165                                  		;
   166 000000CF 1E                      		push	ds
   167 000000D0 07                      		pop	es
   168                                  		;
   169 000000D1 B80006                  		mov 	ax, 0600h  ; Scroll up, clear (AL=0)
   170 000000D4 B717                    		mov	bh, 17h    ; Blue backround (1), 
   171                                  				   ; Light gray foreground (7)
   172 000000D6 29C9                    		sub	cx, cx     ; Left-Upper column, row
   173 000000D8 BA4F18                  		mov	dx, 184Fh  ; Righ-Lower column, row
   174 000000DB CD10                    		int 	10h			 
   175                                  		;
   176 000000DD B402                    		mov	ah, 2	   ; Set cursor position 	
   177 000000DF 29D2                    		sub	dx, dx	   ; Row 0 (DH), Column 0 (DL)	
   178 000000E1 BB0700                  		mov	bx, 7	
   179 000000E4 CD10                    		int 	10h
   180                                  		;
   181                                  		; 28/10/2015
   182 000000E6 29C0                    		sub	ax, ax 	   ; null
   183                                  		; 06/11/2015
   184 000000E8 A3[2004]                		mov	word [ticks], ax ; 0 ; reset timer ticks
   185 000000EB EB7A                                    jmp     short _3 ; query (initialization, wakeup signal)
   186                                  
   187                                  sendchr:
   188                                  		; 10/11/2015
   189 000000ED E8A500                  		call	print  ; move and print received chars on the screen
   190                                  		;
   191 000000F0 3826[1104]              		cmp 	byte [cbrk], ah ; 0 ; ctrl + break
   192 000000F4 7779                                    ja      short _exit
   193                                                  ; 06/11/2015
   194 000000F6 A0[1F04]                		mov 	al, byte [rchar]
   195 000000F9 08C0                    		or	al, al
   196 000000FB 7512                    		jnz	short s4
   197 000000FD FEC8                    		dec	al ; 0FFh
   198 000000FF 3806[1E04]              		cmp	byte [schar], al ; 0FFh
   199 00000103 7423                    		je	short getchr
   200                                  response:
   201                                  		; the remote process is waiting for response !
   202 00000105 A2[1E04]                		mov 	byte [schar], al ; 0FFh  ; response
   203 00000108 FEC0                    		inc	al
   204 0000010A A3[2004]                		mov	word [ticks], ax ; 0 ; reset connection timeout
   205 0000010D EB55                    		jmp	short _2 ; _1
   206                                  s4:
   207 0000010F 3826[1E04]              		cmp 	byte [schar], ah ; 0  ; query (wait for response)
   208 00000113 770B                    		ja	short s5
   209 00000115 3CFF                    		cmp	al, 0FFh ; response
   210 00000117 740F                    		je	short getchr
   211                                  query:
   212                                  		; connection time out ! wait for response ...
   213 00000119 30C0                    		xor	al, al ; ax = 0
   214 0000011B A3[2004]                		mov	word [ticks], ax ;0 ; reset connection timeout
   215 0000011E EB1C                    		jmp	short _1 ; _2	 	
   216                                  s5:
   217 00000120 813E[2004]A101          		cmp	word [ticks], 417
   218 00000126 732D                     		jnb	short rq
   219                                  getchr:	
   220 00000128 B401                    		mov	ah, 1
   221 0000012A CD16                    		int	16h
   222 0000012C 7505                    		jnz	short s6
   223                                  		;hlt
   224                                  		;nop
   225                                  		;nop
   226                                  		;nop
   227                                  		; 10/11/2015
   228                                  		; Do somethings while waiting for
   229                                  		; 'transmitter holding register empty' status
   230                                  		;
   231 0000012E E86400                  		call 	print	; move and print received chars on the screen
   232                                  		;
   233 00000131 EBF5                    		jmp	short getchr
   234                                  s6:
   235 00000133 30E4                    		xor	ah, ah 	   ; 0
   236 00000135 CD16                    		int	16h	   ; Read character
   237                                  		; 28/10/2015
   238 00000137 A2[1E04]                		mov 	byte [schar], al
   239 0000013A 28E4                    		sub	ah, ah
   240                                  _1:
   241                                  		; 06/11/2015
   242 0000013C 3826[1104]              		cmp	byte [cbrk], ah ; exit sign
   243 00000140 772D                    		ja	short _exit
   244                                  		; 29/10/2015
   245 00000142 8B16[0A04]              		mov	dx, word [_3FDh] ; Line status register 
   246 00000146 EC                      		in	al, dx	   ; read register
   247 00000147 EB00                    		JMP	$+2	   ; I/O DELAY
   248 00000149 A880                    		test	al, 80h	   ; time out error
   249 0000014B 740E                    		jz	short s7
   250 0000014D 813E[2004]A101          		cmp	word [ticks], 417
   251 00000153 72E7                     		jb	short _1
   252                                  rq:
   253 00000155 8826[1E04]              		mov 	byte [schar], ah ; 0  ; query (wait for response) 
   254 00000159 EBBE                    		jmp	short query
   255                                  s7:
   256 0000015B 2420                    		and	al, 20h	   ; Transmitter holding reg. empty?
   257 0000015D 7505                    		jnz	short _2   ; yes, ready to send
   258                                  		;
   259                                  		;xor	dh, dh
   260                                  		;mov	dl, byte [port]
   261                                  		;mov	ah, 3
   262                                  		;int	14h
   263                                  		;and	ah, 32 	   ;trasmitter holding register empty
   264                                  		;jnz	short _2   ;yes, ready to send
   265                                  		;
   266                                  		;hlt		   ;no, check status again
   267                                  		;nop
   268                                  		;nop
   269                                  		;jmp	short _1
   270                                  		;
   271                                  		; 10/11/2015
   272                                  		; Do somethings while waiting for 
   273                                  		; 'transmitter holding register empty' status
   274                                  		;
   275 0000015F E83300                  		call 	print	; move and print received chars on the screen
   276                                  		;
   277 00000162 EBD8                    		jmp	short _1
   278                                  _2:
   279 00000164 A0[1E04]                		mov 	al, byte [schar]
   280                                  _3:
   281 00000167 8B16[0404]              		mov	dx, word [_3F8h] ; data port
   282 0000016B EE                      		out	dx, al	   ; send on serial port
   283                                  		; ah = 0
   284                                  		; 10/11/2015
   285 0000016C E97EFF                                  jmp    sendchr
   286                                  
   287                                  _exit:
   288                                  				   ; Restore old interrupt vectors
   289 0000016F 31C0                    		xor	ax, ax
   290 00000171 8EC0                                    mov	es, ax     ; 0
   291 00000173 BE[1A04]                                mov	si, old_serial
   292 00000176 BF2C00                  		mov	di, 0Bh*4 ; (COM2)
   293 00000179 FE0E[1004]              		dec	byte [port] 
   294 0000017D 7403                    		jz	short s8
   295 0000017F 83C704                  		add	di, 4	   ; 0Ch*4 (COM1)
   296                                  s8:
   297 00000182 FA                      		cli
   298 00000183 A5                                      movsw              ; Restore
   299 00000184 A5                                      movsw
   300 00000185 FB                      		sti        
   301                                  _return:
   302 00000186 BE[1204]                		mov	si, old_ctrlbrk
   303 00000189 BF6C00                  		mov	di, 27*4 
   304                                  				   ; INT 1Bh vector
   305 0000018C A5                                      movsw              ; Restore 
   306 0000018D A5                                      movsw
   307                                  		; 06/11/2015
   308                                  		;mov	si, old_timer
   309                                  		;mov	di, 28*4 
   310                                  				   ; INT 1Ch vector
   311 0000018E A5                                      movsw              ; Restore 
   312 0000018F A5                                      movsw
   313                                  		;
   314 00000190 CD20                    		int 20h
   315                                  here:
   316 00000192 F4                      		hlt
   317 00000193 EBFD                    		jmp	 short here
   318                                  
   319                                  print:
   320                                  		; 23/11/2015
   321                                  		; 10/11/2015
   322                                  		;
   323                                  		; write received chars (in buffer) to screen
   324                                  		;
   325 00000195 BE[2205]                		mov	si, rbuffer
   326 00000198 BF[2204]                		mov	di, wbuffer
   327 0000019B 893E[0E04]              		mov	word [wb_off], di
   328 0000019F 9C                      		pushf ; 23/11/2015
   329 000001A0 FA                      		cli	; interrupts off		
   330 000001A1 8B0E[0C04]              		mov	cx, word [rb_off] ; read buffer offset
   331 000001A5 29F1                    		sub	cx, si
   332 000001A7 7702                    		ja	short p0
   333                                  		; empty buffer !
   334                                  		;sti	; interrupts on	
   335 000001A9 9D                      		popf ; 23/11/2015
   336 000001AA C3                      		retn
   337                                  p0:
   338                                  		; move chars to writing buffer (from reading buffer)
   339                                  		; while serial port interrupt is disabled
   340                                  		;
   341 000001AB 010E[0E04]              		add	word [wb_off], cx ; byte/char count
   342                                  		;
   343 000001AF F3A4                    		rep	movsb
   344                                  		;
   345 000001B1 C706[0C04][2205]        		mov	word [rb_off], rbuffer ; reset
   346                                  		;sti	; interrupts on
   347 000001B7 9D                      		popf ; 23/11/2015
   348                                  		;
   349 000001B8 BE[2204]                		mov	si, wbuffer
   350                                  		;
   351 000001BB BB0700                  		mov	bx, 7    ; video page 0, color 7
   352 000001BE B40E                    		mov	ah, 0Eh  ; write chars as teletype output
   353                                  p1:	
   354                                  		; print chars (in writing buffer) on the screen
   355                                  		; while serial port interrupt is enabled (again)
   356                                  		;
   357 000001C0 AC                      		lodsb
   358                                  		;
   359                                  		; 26/10/2015
   360 000001C1 3C09                    		cmp 	al, 9	   ; TAB key ?
   361 000001C3 751E                    		jne	short p3
   362 000001C5 51                      		push	cx
   363 000001C6 B403                    		mov 	ah, 3	  ; Get cursor position
   364                                  		;mov	bh, 0
   365 000001C8 CD10                    		int 	10h
   366 000001CA 59                      		pop 	cx
   367 000001CB 30E4                    		xor	ah, ah
   368 000001CD 88D0                    		mov	al, dl	   ; row
   369 000001CF B208                    		mov	dl, 8
   370 000001D1 F6F2                    		div	dl
   371 000001D3 B208                    		mov 	dl, 8
   372 000001D5 28E2                    		sub	dl, ah
   373 000001D7 B020                    		mov	al, 20h
   374 000001D9 B40E                    		mov	ah, 0Eh
   375                                  		;mov	bx, 7
   376                                  p2:
   377 000001DB FECA                    		dec	dl
   378 000001DD 7404                    		jz	short p3
   379 000001DF CD10                    		int	10h	   ; Write character on TTY display
   380 000001E1 EBF8                    		jmp 	short p2	
   381                                  p3:
   382 000001E3 CD10                    		int	10h	   ; Write character on TTY display
   383                                  		;
   384                                  		; 10/11/2015
   385 000001E5 3B36[0E04]              		cmp	si, word [wb_off]
   386 000001E9 72D5                    		jb	short p1
   387 000001EB C3                      		retn
   388                                  
   389                                  serial:		
   390                                  		; 10/11/2015
   391                                  		; 06/11/2015
   392                                  		; 28/10/2015
   393                                  		; 26/10/2015
   394                                  		;
   395                                                  ; INT 0Ch (0Bh) serial port interrupt handler        
   396                                  		;
   397 000001EC 1E                      		push	ds
   398 000001ED 50                      		push	ax
   399 000001EE 53                      		push	bx
   400 000001EF 52                      		push	dx
   401                                  		;
   402 000001F0 8CC8                    		mov	ax, cs
   403 000001F2 8ED8                    		mov	ds, ax
   404                                  		;
   405                                  		; 06/11/2015
   406 000001F4 C706[2004]0000          		mov	word [ticks], 0 ; Reset connection timeout
   407                                  		;
   408                                  		; 28/10/2015
   409 000001FA 8B16[0A04]              		mov	dx, word [_3FDh] ; Line status register 
   410 000001FE EC                      		in	al, dx	   ; read register
   411 000001FF EB00                    		JMP	$+2	   ; I/O DELAY
   412 00000201 2401                    		and	al, 01h	   ; Data ready?
   413 00000203 744B                    		jz	short _6   ; no
   414                                  		; 28/10/2015
   415 00000205 8B16[0404]              		mov	dx, word [_3F8h]
   416                                  				   ;data register
   417 00000209 EC                      		in	al, dx     ;read character
   418 0000020A EB00                    		JMP	$+2	   ; I/O DELAY
   419                                  		; 06/11/2015
   420 0000020C A2[1F04]                		mov	byte [rchar], al ; received char
   421                                  		; query
   422 0000020F 20C0                    		and 	al, al	   ; 0
   423 00000211 751C                    		jnz	short _4
   424                                                  ; response
   425 00000213 C606[1E04]00            		mov 	byte [schar], 0
   426 00000218 8B16[0A04]              		mov	dx, word [_3FDh] ; Line status register 
   427 0000021C EC                      		in	al, dx	   ; read register
   428 0000021D EB00                    		JMP	$+2	   ; I/O DELAY
   429 0000021F 2420                    		and	al, 20h	   ; Transmitter holding reg. empty?
   430 00000221 742D                    		jz	short _6   ; no
   431                                  		;
   432 00000223 B0FF                    		mov 	al, 0FFh   ; response			
   433 00000225 8B16[0404]              		mov	dx, word [_3F8h] ; data port
   434 00000229 EE                      		out	dx, al	   ; send on serial port
   435                                  		;JMP	$+2	   ; I/O DELAY
   436 0000022A A2[1E04]                		mov	byte [schar], al ; 0FFh
   437 0000022D EB21                    		jmp	short _6
   438                                  _4:
   439                                  		; 06/11/2015
   440 0000022F FEC0                    		inc	al	  ; al = FFh -> 0
   441 00000231 741D                    		jz	short _6  ; al = 0 (response, FFh)
   442 00000233 FEC8                    		dec	al		
   443                                  		; 10/11/2015 - Receive char and put it in read buffer
   444 00000235 8B1E[0C04]              		mov	bx, word [rb_off] ; read buffer offset
   445 00000239 BA[2206]                		mov 	dx, rbuffer + 256
   446 0000023C 39D3                    		cmp	bx, dx
   447 0000023E 7209                    		jb	short _5
   448                                  		; 23/11/2015
   449                                  		; buffer is full!
   450 00000240 50                      		push	ax
   451 00000241 E851FF                  		call	print
   452 00000244 8B1E[0C04]              		mov	bx, word [rb_off]	
   453 00000248 58                      		pop	ax
   454                                  _5:
   455 00000249 8807                                    mov     byte [bx], al  ; put character in buffer
   456 0000024B 43                      		inc	bx	 ; points to next char address in buffer	
   457 0000024C 891E[0C04]              		mov	word [rb_off], bx ; read buffer offset
   458                                  _6:
   459 00000250 B020                    		mov	al, 20h
   460 00000252 E620                    		out	20h, al	   ;end of interrupt
   461                                  		;
   462 00000254 5A                      		pop	dx
   463 00000255 5B                      		pop	bx
   464 00000256 58                      		pop	ax
   465 00000257 1F                      		pop	ds
   466 00000258 CF                      		iret		
   467                                  
   468                                  ctrlbrk:
   469                                  		; INT 1Bh (control+break) handler		
   470                                  		;
   471 00000259 2EFE06[1104]                            inc     byte [CS:cbrk] 
   472 0000025E CF                      		iret
   473                                  _timer:
   474                                  		; 06/11/2015
   475                                  		; INT 1Ch (periodic timer interrupt (18.2 times per second)		
   476                                  		;
   477 0000025F 2EFF06[2004]                            inc     word [CS:ticks]
   478                                  		;iret 
   479 00000264 2EFF2E[1604]                            jmp     far [CS:old_timer] 
   480                                  
   481                                  proc_printmsg:
   482 00000269 B40E                    		mov	ah, 0Eh
   483                                  		;mov	bx, 7
   484                                  s9:
   485 0000026B AC                      		lodsb
   486 0000026C 20C0                    		and	al, al
   487 0000026E 7404                    		jz	short s10
   488 00000270 CD10                    		int 	10h
   489 00000272 EBF7                    		jmp	short s9
   490                                  s10:          
   491 00000274 C3                      		retn
   492                                  
   493                                  set_spcp: ; Set serial port communication parameters
   494                                  	; 26/10/2015 (SERIAL3.ASM)
   495                                  	; 29/06/2015 (Retro UNIX 386 v1 - u0.s)
   496                                  	;
   497                                  	;  Communication parameters (except BAUD RATE):
   498                                  	;	Bit	4	3	2	1	0
   499                                  	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   500                                  	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   501                                  	;		01 = odd     1 = 2 bits	10 = 7 bits
   502                                  	;		11 = even
   503                                  	;  Baud rate setting bits: (29/06/2015)
   504                                  	;		Retro UNIX 386 v1 feature only !
   505                                  	;	Bit	7    6    5  | Baud rate
   506                                  	;		------------------------
   507                                  	;	value	0    0    0  | Default (Divisor = 1)
   508                                  	;		0    0    1  | 9600 (12)
   509                                  	;		0    1    0  | 19200 (6) 
   510                                  	;		0    1	  1  | 38400 (3) 
   511                                  	;		1    0	  0  | 14400 (8)
   512                                  	;		1    0	  1  | 28800 (4)
   513                                  	;		1    1    0  | 57600 (2)
   514                                  	;		1    1    1  | 115200 (1) 
   515                                  	;	
   516                                  	; References:	
   517                                  	; (1) IBM PC-XT Model 286 BIOS Source Code
   518                                  	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   519                                  	; (2) Award BIOS 1999 - ATORGS.ASM
   520                                  	; (3) http://wiki.osdev.org/Serial_Ports
   521                                  	;
   522                                  	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   523                                  	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   524                                  	;
   525                                  	; ((Modified registers: EAX, ECX, EDX, EBX))
   526                                  	;
   527                                  	;mov	cl, 1 ; divisor = 1 (115200 baud)
   528                                  	;mov	ch, 3 ; communication parameters except divisor 
   529 00000275 B90103                  	mov	cx, 301h
   530                                  sp_i1:
   531 00000278 BAF803                  	mov	dx, 3F8h  ; COM1 Data register
   532                                  	; 26/10/2015
   533 0000027B A0[1004]                	mov 	al, byte [port]
   534 0000027E 08C0                    	or	al, al
   535 00000280 7402                    	jz	short sp_i2 ;  COM1 (AL = 0)
   536                                  	;
   537 00000282 FECE                    	dec	dh ; 2F8h, COM2 Data register
   538                                  sp_i2:
   539                                    	;-----	INITIALIZE THE COMMUNICATIONS PORT
   540                                  	; 28/10/2015
   541 00000284 FEC2                    	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   542 00000286 B000                    	mov	al, 0
   543 00000288 EE                      	out	dx, al			; disable serial port interrupt
   544 00000289 EB00                    	JMP	$+2			; I/O DELAY
   545 0000028B 80C202                  	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   546 0000028E B080                    	mov	al, 80h			
   547 00000290 EE                      	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   548 00000291 EB00                    	JMP	$+2			; I/O DELAY
   549                                  	;-----	SET BAUD RATE DIVISOR
   550                                  	; 26/10/2015
   551 00000293 80EA03                  	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   552                                  					; of the divisor value
   553 00000296 88C8                    	mov	al, cl	; 1
   554 00000298 EE                      	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   555                                  					; 2 = 57600 baud
   556                                  					; 3 = 38400 baud
   557                                  					; 6 = 19200 baud
   558                                  					; 12 = 9600 baud (Retro UNIX 8086 v1)
   559 00000299 EB00                    	JMP	$+2			; I/O DELAY
   560 0000029B 28C0                    	sub	al, al
   561 0000029D FEC2                    	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   562                                  					; of the divisor value
   563 0000029F EE                      	out	dx, al ; 0
   564 000002A0 EB00                    	JMP	$+2			; I/O DELAY
   565                                  	;	
   566 000002A2 88E8                    	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   567                                  	;and	al, 1Fh ; Bits 0,1,2,3,4	
   568 000002A4 80C202                  	add	dl, 2	; 3FBh (2FBh)	; Line control register
   569 000002A7 EE                      	out	dx, al			
   570 000002A8 EB00                    	JMP	$+2			; I/O DELAY
   571                                  	; 29/10/2015
   572 000002AA FECA                    	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   573 000002AC 30C0                    	xor	al, al			; 0
   574 000002AE EE                      	out	dx, al			; Disable FIFOs (reset to 8250 mode)	
   575 000002AF EB00                    	JMP	$+2
   576                                  sp_i3:
   577                                  	;-----	COMM PORT STATUS ROUTINE
   578                                  	; 28/10/2015
   579                                  	; 26/10/2015
   580 000002B1 80C203                  	add	dl, 3	; 3FDh (2FDh)	; COM1 Line status register (3FDh) 
   581 000002B4 8A26[2206]              	mov	ah, byte [error]
   582 000002B8 08E4                    	or	ah, ah ; 0?
   583 000002BA 7512                    	jnz	short sp_i4 ; error! 
   584 000002BC EC                      	in	al, dx			; GET LINE CONTROL STATUS
   585 000002BD EB00                    	JMP	$+2			; I/O DELAY
   586 000002BF A880                    	test	al, 80h			; Timeout!?
   587 000002C1 740D                    	jz	short sp_i5
   588 000002C3 FEC4                    	inc	ah ; 1
   589 000002C5 8826[2206]              	mov	byte [error], ah
   590 000002C9 B90E03                          mov     cx, 30Eh 		; Reset to 9600 baud
   591 000002CC EBAA                    	jmp 	short sp_i1
   592                                  sp_i4:
   593 000002CE F9                      	stc
   594 000002CF C3                      	retn
   595                                  sp_i5:
   596                                  	; 02/11/2015
   597                                  	; 28/10/2015
   598                                  	; 26/10/2015
   599                                  	; 29/06/2015
   600                                  	;; COM1 - enabling IRQ 4
   601                                  	;; (COM2 - enabling IRQ 3)
   602 000002D0 8B16[0804]              	mov	dx, word [_3FCh]	; modem control register
   603 000002D4 EC                      	in	al, dx 	   		; read register
   604 000002D5 EB00                    	JMP	$+2			; I/O DELAY
   605 000002D7 0C08                    	or	al, 8      		; enable bit 3 (OUT2)
   606 000002D9 EE                      	out	dx, al     		; write back to register
   607 000002DA EB00                    	JMP	$+2			; I/O DELAY
   608 000002DC 8B16[0604]              	mov	dx, word [_3F9h]	; interrupt enable register
   609 000002E0 EC                      	in	al, dx     		; read register
   610 000002E1 EB00                    	JMP	$+2			; I/O DELAY
   611                                  	;or	al, 3      		; transmitter empty 
   612                                  					; interrupt enable and
   613 000002E3 0C01                    	or	al, 1			; receiver data interrupt enable
   614 000002E5 EE                      	out	dx, al 	   		; write back to register
   615 000002E6 EB00                    	JMP	$+2        		; I/O DELAY
   616 000002E8 E421                    	in	al, 21h    		; read interrupt mask register
   617 000002EA EB00                    	JMP	$+2        		; I/O DELAY
   618 000002EC 2206[0204]                      and     al, byte [_EFh]     ; enable IRQ 4 (IRQ 3)
   619 000002F0 E621                    	out	21h, al    		; write back to register
   620                                  	;
   621 000002F2 C3                      	retn
   622                                  
   623                                  StartMsg:
   624 000002F3 0D0A                                    db 0Dh,0Ah
   625 000002F5 5465726D696E616C20-                     db 'Terminal program for Retro UNIX 386 v1... (23/11/2015)'
   626 000002FE 70726F6772616D2066-
   627 00000307 6F7220526574726F20-
   628 00000310 554E49582033383620-
   629 00000319 76312E2E2E20283233-
   630 00000322 2F31312F3230313529 
   631 0000032B 0D0A                    		db 0Dh, 0Ah
   632 0000032D 28274374726C2B4272-                     db "('Ctrl+Break' must be used to exit!)"
   633 00000336 65616B27206D757374-
   634 0000033F 206265207573656420-
   635 00000348 746F20657869742129 
   636 00000351 0D0A                                    db 0Dh, 0Ah
   637 00000353 0D0A                    		db 0Dh, 0Ah
   638 00000355 507265737320312066-     		db 'Press 1 for COM 1 or press 2 for COM2 serial port...' 
   639 0000035E 6F7220434F4D203120-
   640 00000367 6F7220707265737320-
   641 00000370 3220666F7220434F4D-
   642 00000379 322073657269616C20-
   643 00000382 706F72742E2E2E     
   644 00000389 0D0A                    		db 0Dh, 0Ah
   645 0000038B 0D0A00                  		db 0Dh,0Ah,0h
   646                                  ComSMsg:
   647 0000038E 07                      		db 07h
   648 0000038F 434F4D312073656C65-     		db 'COM1 selected...'
   649 00000398 637465642E2E2E     
   650 0000039F 0D0A00                  		db  0Dh, 0Ah, 0
   651                                  AnyKeyMsg:
   652 000003A2 50726573732061206B-                     db "Press a key to continue. (Press 'ESC' key to cancel.)"
   653 000003AB 657920746F20636F6E-
   654 000003B4 74696E75652E202850-
   655 000003BD 726573732027455343-
   656 000003C6 27206B657920746F20-
   657 000003CF 63616E63656C2E29   
   658 000003D7 0D0A00                                  db 0Dh,0Ah,0h
   659                                  ErrMsg:
   660 000003DA 0D0A                    		db 0Dh, 0Ah
   661 000003DC 0D0A                    		db 0Dh, 0Ah
   662 000003DE 53657269616C20506F-     		db 'Serial Port (115200 baud) Error !'
   663 000003E7 727420283131353230-
   664 000003F0 302062617564292045-
   665 000003F9 72726F722021       
   666 000003FF 0D0A00                  		db 0Dh, 0Ah, 0
   667                                  align 2
   668                                  
   669 00000402 EF00                    _EFh:		dw 0EFh
   670                                  ;
   671 00000404 F803                    _3F8h:		dw 3F8h
   672 00000406 F903                    _3F9h:		dw 3F9h
   673                                  ;_3FAh:		dw 3FAh
   674                                  ;_3FBh:		dw 3FBh
   675 00000408 FC03                    _3FCh:		dw 3FCh
   676 0000040A FD03                    _3FDh:		dw 3FDh	
   677                                  ;_3FEh:		dw 3FEh	
   678                                  ;
   679                                  
   680                                  ; 10/11/2015
   681 0000040C [2205]                  rb_off:		dw rbuffer  ; Write buffer offset
   682 0000040E [2204]                  wb_off:		dw wbuffer  ; Read buffer offset
   683                                  
   684                                  ;; align 2
   685                                  
   686                                  ; 10/11/2015 (bss)
   687                                  bss_start:
   688                                  
   689                                  ABSOLUTE bss_start
   690                                  
   691 00000410 <res 00000001>          port:		resb 1
   692 00000411 <res 00000001>          cbrk:		resb 1
   693                                  
   694 00000412 <res 00000004>          old_ctrlbrk:	resd 1
   695 00000416 <res 00000004>          old_timer:	resd 1 ; 06/11/2015
   696 0000041A <res 00000004>          old_serial:	resd 1
   697                                  
   698                                  ; 06/11/2015
   699 0000041E <res 00000001>          schar:		resb 1
   700 0000041F <res 00000001>          rchar:		resb 1
   701 00000420 <res 00000002>          ticks:		resw 1
   702                                  
   703 00000422 <res 00000100>          wbuffer:	resb 256 ; Print (with INT 10h) routine will use this one
   704                                  
   705 00000522 <res 00000100>          rbuffer:	resb 256 ; Interrupt handler will use this one
   706                                  
   707 00000622 <res 00000001>          error:		resb 1
   708 00000623 <res 00000001>          		resb 1
   709                                  
   710                                  bss_end:
