Changeset 601 in xtideuniversalbios for trunk/Assembly_Library/Src/Serial
- Timestamp:
- Feb 14, 2019, 7:38:08 PM (6 years ago)
- Location:
- trunk/Assembly_Library/Src/Serial
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Assembly_Library/Src/Serial/SerialServer.asm
r592 r601 38 38 ;-------------------------------------------------------------------- 39 39 SerialServer_SendReceive: 40 41 push si 42 push di 43 push bp 40 push si 41 push di 42 push bp 44 43 45 44 ; … … 48 47 ; Baud in CH until UART initialization is complete 49 48 ; 50 mov ch,dh51 xor dh,dh52 eSHL_IM dx, 2; shift from one byte to two53 54 mov al,[bp+SerialServer_Command.bSectorCount]55 mov ah,[bp+SerialServer_Command.bCommand]49 mov ch, dh 50 xor dh, dh 51 eSHL_IM dx, 2 ; shift from one byte to two 52 53 mov al, [bp+SerialServer_Command.bSectorCount] 54 mov ah, [bp+SerialServer_Command.bCommand] 56 55 57 56 ; 58 57 ; Command byte and sector count live at the top of the stack, pop/push are used to access 59 58 ; 60 push ax; save sector count for return value61 push ax; working copy on the top of the stack62 63 %ifndef EXCLUDE_FROM_XUB ; DF already cleared in Int13h.asm59 push ax ; save sector count for return value 60 push ax ; working copy on the top of the stack 61 62 %ifndef EXCLUDE_FROM_XUB ; DF already cleared in Int13h.asm 64 63 %ifdef CLD_NEEDED 65 64 cld 66 65 %endif 67 66 %endif … … 74 73 ; decided to reprogram the UART 75 74 ; 76 mov bl,dl ; setup BL with proper values for read/write loops (BH comes later) 77 78 mov al,83h 79 add dl, Serial_UART_lineControl ; Clears CF 80 out dx,al 81 82 mov al,ch 83 mov dl,bl ; divisor low 84 out dx,al 75 mov bl, dl ; setup BL with proper values for read/write loops (BH comes later) 76 mov al, 83h 77 add dl, Serial_UART_lineControl ; Clears CF 78 out dx, al 79 80 mov al, ch 81 mov dl, bl ; divisor low 82 out dx, al 85 83 86 84 %ifdef USE_UNDOC_INTEL 87 salc; Clear AL using CF85 salc ; Clear AL using CF 88 86 %else 89 90 %endif 91 inc dx; divisor high92 93 out dx,al94 95 mov al,047h96 inc dx; fifo97 out dx,al98 99 mov al,03h100 inc dx; linecontrol101 out dx,al102 103 mov al,0bh104 inc dx; modemcontrol105 out dx,al106 107 inc dx; linestatus (no output now, just setting up BH for later use)108 mov bh,dl109 110 pop dx; base, interrupts disabled87 xor al, al 88 %endif 89 inc dx ; divisor high 90 push dx 91 out dx, al 92 93 mov al, 47h 94 inc dx ; fifo 95 out dx, al 96 97 mov al, 03h 98 inc dx ; linecontrol 99 out dx, al 100 101 mov al, 0Bh 102 inc dx ; modemcontrol 103 out dx, al 104 105 inc dx ; linestatus (no output now, just setting up BH for later use) 106 mov bh, dl 107 108 pop dx ; base, interrupts disabled 111 109 %ifdef USE_UNDOC_INTEL 112 salc; Clear AL using CF110 salc ; Clear AL using CF 113 111 %else 114 115 %endif 116 out dx,al112 xor al, al 113 %endif 114 out dx, al 117 115 118 116 ;---------------------------------------------------------------------- … … 122 120 ; Sends first six bytes of IDEREGS_AND_INTPACK as the command 123 121 ; 124 push es; save off real buffer location125 126 127 mov si,bp; point to IDEREGS for command dispatch;128 129 130 131 mov di,0ffffh; initialize checksum for write132 mov bp,di133 134 mov cx,4; writing 3 words (plus 1)135 136 cli; interrupts off...137 138 139 140 pop di; restore real buffer location (note change from SI to DI)141 ; Buffer is primarily referenced through ES:DI throughout, since142 ; we need to store (read sector) faster than we read (write sector)143 144 145 pop ax; load command byte (done before call to .nextSector on subsequent iterations)146 122 push es ; save off real buffer location 123 push si 124 125 mov si, bp ; point to IDEREGS for command dispatch; 126 push ss 127 pop es 128 129 mov di, 0FFFFh ; initialize checksum for write 130 mov bp, di 131 132 mov cx, 4 ; writing 3 words (plus 1) 133 134 cli ; interrupts off... 135 136 call SerialServer_WriteProtocol.entry 137 138 pop di ; restore real buffer location (note change from SI to DI) 139 ; Buffer is primarily referenced through ES:DI throughout, since 140 ; we need to store (read sector) faster than we read (write sector) 141 pop es 142 143 pop ax ; load command byte (done before call to .nextSector on subsequent iterations) 144 push ax 147 145 148 146 %ifndef SERIALSERVER_NO_ZERO_SECTOR_COUNTS 149 test al,al; if no sectors to be transferred, wait for the ACK checksum on the command150 jz.zeroSectors147 test al, al ; if no sectors to be transferred, wait for the ACK checksum on the command 148 jz SHORT .zeroSectors 151 149 %endif 152 150 … … 155 153 ; 156 154 .nextSector: 157 mov si,0ffffh; initialize checksum for read or write158 mov bp,si159 160 mov cx,0101h; writing 256 words (plus 1)161 162 sahf; command byte, are we doing a write?163 jnc.readEntry164 165 xchg si,di; swap pointer and checksum, will be re-swap'ed in WriteProtocol166 155 mov si, 0FFFFh ; initialize checksum for read or write 156 mov bp, si 157 158 mov cx, 0101h ; writing 256 words (plus 1) 159 160 sahf ; command byte, are we doing a write? 161 jnc SHORT .readEntry 162 163 xchg si, di ; swap pointer and checksum, will be re-swap'ed in WriteProtocol 164 call SerialServer_WriteProtocol.entry 167 165 168 166 .zeroSectors: 169 inc cx; CX = 1 now (0 out of WriteProtocol)170 jmp.readEntry167 inc cx ; CX = 1 now (0 out of WriteProtocol) 168 jmp SHORT .readEntry 171 169 172 170 ;---------------------------------------------------------------------- … … 177 175 ; 178 176 .readTimeout: 179 push ax; not only does this push preserve AX (which we need), but it also180 ; means the stack has the same number of bytes on it as when we are181 ; sending a packet, important for error cleanup and exit182 mov ah,1183 184 185 test dl,1186 jz.readByte1Ready187 jmp.readByte2Ready177 push ax ; not only does this push preserve AX (which we need), but it also 178 ; means the stack has the same number of bytes on it as when we are 179 ; sending a packet, important for error cleanup and exit 180 mov ah, 1 181 call SerialServer_WaitAndPoll_Read 182 pop ax 183 test dl, 1 184 jz SHORT .readByte1Ready 185 jmp SHORT .readByte2Ready 188 186 189 187 ;---------------------------------------------------------------------------- … … 197 195 ; 198 196 .readLoop: 199 stosw; store word in caller's data buffer200 201 add bp, ax; update Fletcher's checksum202 203 204 197 stosw ; store word in caller's data buffer 198 199 add bp, ax ; update Fletcher's checksum 200 adc bp, 0 201 add si, bp 202 adc si, 0 205 203 206 204 .readEntry: 207 mov dl,bh208 in al,dx209 shr al,1; data ready (byte 1)?210 mov dl,bl; get ready to read data211 jnc .readTimeout; nope not ready, update timeouts205 mov dl, bh 206 in al, dx 207 shr al, 1 ; data ready (byte 1)? 208 mov dl, bl ; get ready to read data 209 jnc SHORT .readTimeout ; nope not ready, update timeouts 212 210 213 211 ; … … 216 214 ; 217 215 .readByte1Ready: 218 in al, dx ; read data byte 1 219 220 mov ah, al ; store byte in ah for now 216 in al, dx ; read data byte 1 217 mov ah, al ; store byte in ah for now 221 218 222 219 ; … … 227 224 ; .read_byte2_ready) 228 225 ; 229 mov dl,bh230 231 in al,dx232 shr al,1; data ready (byte 2)?233 jnc.readTimeout226 mov dl, bh 227 228 in al, dx 229 shr al, 1 ; data ready (byte 2)? 230 jnc SHORT .readTimeout 234 231 .readByte2Ready: 235 mov dl,bl 236 in al, dx ; read data byte 2 237 238 xchg al, ah ; ah was holding byte 1, reverse byte order 239 240 loop .readLoop 241 242 sti ; interrupts back on ASAP, between packets 232 mov dl, bl 233 in al, dx ; read data byte 2 234 xchg al, ah ; ah was holding byte 1, reverse byte order 235 loop .readLoop 236 sti ; interrupts back on ASAP, between packets 243 237 244 238 ; 245 239 ; Compare checksums 246 240 ; 247 xchg ax,bp 248 xor ah,al 249 mov cx,si 250 xor cl,ch 251 mov al,cl 252 cmp ax,bp 253 jnz SerialServer_OutputWithParameters_Error 254 255 pop ax ; sector count and command byte 256 dec al ; decrement sector count 257 push ax ; save 258 jz SerialServer_OutputWithParameters_ReturnCodeInAL 259 260 cli ; interrupts back off for ACK byte to host 261 ; (host could start sending data immediately) 262 out dx,al ; ACK with next sector number 263 264 jmp short .nextSector 241 xchg ax, bp 242 xor ah, al 243 mov cx, si 244 xor cl, ch 245 mov al, cl 246 cmp ax, bp 247 jne SHORT SerialServer_OutputWithParameters_Error 248 249 pop ax ; sector count and command byte 250 dec al ; decrement sector count 251 push ax ; save 252 jz SHORT SerialServer_OutputWithParameters_ReturnCodeInAL 253 254 cli ; interrupts back off for ACK byte to host 255 ; (host could start sending data immediately) 256 out dx, al ; ACK with next sector number 257 jmp SHORT .nextSector 265 258 266 259 ;--------------------------------------------------------------------------- … … 274 267 ALIGN JUMP_ALIGN 275 268 SerialServer_OutputWithParameters_ErrorAndPop4Words: 276 add sp,8269 add sp, 8 277 270 ;;; fall-through 278 271 … … 287 280 ; taken care of this, but I have seen cases where this is not true. 288 281 ; 289 xor cx,cx; timeout this clearing routine, in case the UART isn't there282 xor cx, cx ; timeout this clearing routine, in case the UART isn't there 290 283 .clearBuffer: 291 mov dl,bh292 in al,dx293 mov dl,bl294 test al,08fh295 jz.clearBufferComplete296 test al,1297 in al,dx298 loopnz .clearBuffer; note ZF from test above284 mov dl, bh 285 in al, dx 286 mov dl, bl 287 test al, 8Fh 288 jz SHORT .clearBufferComplete 289 test al, 1 290 in al, dx 291 loopnz .clearBuffer ; note ZF from test above 299 292 300 293 .clearBufferComplete: 301 mov al, 1; error return code294 mov al, 1 ; error return code 302 295 303 296 ALIGN JUMP_ALIGN 304 297 SerialServer_OutputWithParameters_ReturnCodeInAL: 305 298 %if 0 306 sti; all paths here will already have interrupts turned back on307 %endif 308 mov ah, al; for success, AL will already be zero309 310 pop bx; recover "ax" (command and count) from stack311 pop cx; recover saved sector count312 313 sub cl, bl; subtract off the number of sectors that remained314 315 316 317 318 319 sahf; error return code to CF320 321 ret 299 sti ; all paths here will already have interrupts turned back on 300 %endif 301 mov ah, al ; for success, AL will already be zero 302 303 pop bx ; recover "ax" (command and count) from stack 304 pop cx ; recover saved sector count 305 xor ch, ch 306 sub cl, bl ; subtract off the number of sectors that remained 307 308 pop bp 309 pop di 310 pop si 311 312 sahf ; error return code to CF 313 ret 314 322 315 323 316 ;-------------------------------------------------------------------- … … 345 338 SerialServer_WriteProtocol: 346 339 .writeLoop: 347 es lodsw; fetch next word348 349 out dx,al; output first byte350 351 add bp,ax; update checksum352 adc bp,0353 add di,bp354 adc di,0355 356 mov dl,bh; transmit buffer empty?357 in al,dx358 test al,20h359 jz .writeTimeout2; nope, use our polling routine340 es lodsw ; fetch next word 341 342 out dx, al ; output first byte 343 344 add bp, ax ; update checksum 345 adc bp, 0 346 add di, bp 347 adc di, 0 348 349 mov dl, bh ; transmit buffer empty? 350 in al, dx 351 test al, 20h 352 jz SHORT .writeTimeout2 ; nope, use our polling routine 360 353 361 354 .writeByte2Ready: 362 mov dl,bl363 mov al,ah; output second byte364 out dx,al355 mov dl, bl 356 mov al, ah ; output second byte 357 out dx, al 365 358 366 359 .entry: 367 mov dl,bh; transmit buffer empty?368 in al,dx369 test al,20h370 mov dl,bl371 jz .writeTimeout1; nope, use our polling routine360 mov dl, bh ; transmit buffer empty? 361 in al, dx 362 test al, 20h 363 mov dl, bl 364 jz SHORT .writeTimeout1 ; nope, use our polling routine 372 365 373 366 .writeByte1Ready: 374 loop .writeLoop 375 376 mov ax,di ; fold Fletcher's checksum and output 377 xor al,ah 378 out dx,al ; byte 1 379 380 call SerialServer_WaitAndPoll_Write 381 382 mov ax,bp 383 xor al,ah 384 out dx,al ; byte 2 385 386 xchg si,di ; preserve checksum word in si, move pointer back to di 387 388 ret 367 loop .writeLoop 368 369 mov ax, di ; fold Fletcher's checksum and output 370 xor al, ah 371 out dx, al ; byte 1 372 373 call SerialServer_WaitAndPoll_Write 374 375 mov ax, bp 376 xor al, ah 377 out dx, al ; byte 2 378 379 xchg si, di ; preserve checksum word in si, move pointer back to di 380 ret 389 381 390 382 .writeTimeout2: 391 mov dl,ah; need to preserve AH, but don't need DL (will be reset upon return)392 393 mov ah,dl394 jmp.writeByte2Ready383 mov dl, ah ; need to preserve AH, but don't need DL (will be reset upon return) 384 call SerialServer_WaitAndPoll_Write 385 mov ah, dl 386 jmp SHORT .writeByte2Ready 395 387 396 388 .writeTimeout1: 397 ePUSH_T ax, .writeByte1Ready; return address for ret at end of SC_writeTimeout2389 ePUSH_T ax, .writeByte1Ready ; return address for ret at end of SC_writeTimeout2 398 390 ;;; fall-through 399 391 … … 418 410 ALIGN JUMP_ALIGN 419 411 SerialServer_WaitAndPoll_Write: 420 mov ah,20h412 mov ah, 20h 421 413 ;;; fall-through 422 414 423 415 ALIGN JUMP_ALIGN 424 416 SerialServer_WaitAndPoll_Read: 425 426 417 push cx 418 push dx 427 419 428 420 ; 429 421 ; We first poll in a tight loop, interrupts off, for the next character to come in/be sent 430 422 ; 431 xor cx,cx423 xor cx, cx 432 424 .readTimeoutLoop: 433 mov dl,bh434 in al,dx435 test al,ah436 jnz.readTimeoutComplete437 425 mov dl, bh 426 in al, dx 427 test al, ah 428 jnz SHORT .readTimeoutComplete 429 loop .readTimeoutLoop 438 430 439 431 ; … … 441 433 ; and wait for a given number of timer ticks to pass. 442 434 ; 443 435 sti 444 436 %ifndef SERIALSERVER_TIMER_LOCATION 445 mov cl,SerialServer_WaitAndPoll_SoftDelayTicks446 437 mov cl, SerialServer_WaitAndPoll_SoftDelayTicks 438 call Timer_InitializeTimeoutWithTicksInCL 447 439 %else 448 449 450 mov ax,SerialServer_WaitAndPoll_SoftDelayTicks451 mov bx,SERIALSERVER_TIMER_LOCATION452 453 454 440 push ax 441 push bx 442 mov ax, SerialServer_WaitAndPoll_SoftDelayTicks 443 mov bx, SERIALSERVER_TIMER_LOCATION 444 call TimerTicks_InitializeTimeoutFromAX 445 pop bx 446 pop ax 455 447 %endif 456 448 457 449 .WaitAndPoll: 458 450 %ifndef SERIALSERVER_TIMER_LOCATION 459 451 call Timer_SetCFifTimeout 460 452 %else 461 462 463 mov bx,SERIALSERVER_TIMER_LOCATION464 465 466 467 %endif 468 469 in al,dx470 test al,ah471 jz.WaitAndPoll472 453 push ax 454 push bx 455 mov bx, SERIALSERVER_TIMER_LOCATION 456 call TimerTicks_GetTimeoutTicksLeftToAXfromDSBX 457 pop bx 458 pop ax 459 %endif 460 jc SerialServer_OutputWithParameters_ErrorAndPop4Words 461 in al, dx 462 test al, ah 463 jz SHORT .WaitAndPoll 464 cli 473 465 474 466 .readTimeoutComplete: 475 pop dx 476 pop cx 477 ret 478 479 467 pop dx 468 pop cx 469 ret 470 -
trunk/Assembly_Library/Src/Serial/SerialServerScan.asm
r589 r601 1 1 ; Project name : Assembly Library 2 2 ; Description : Serial Server Support, Scan for Server 3 3 4 ; 4 5 ; This functionality is broken out from SerialServer as it may only be needed during … … 43 44 ;-------------------------------------------------------------------- 44 45 SerialServerScan_ScanForServer: 45 46 mov cx, 1 ; one sector, not scanning (default) 46 47 47 48 48 test dx, dx 49 jnz SHORT SerialServerScan_CheckForServer_PortAndBaudInDX 49 50 50 51 51 mov di, .scanPortAddresses-1 52 mov ch, 1 ; tell server that we are scanning 52 53 53 54 .nextPort: 54 55 56 57 58 55 inc di ; load next port address 56 mov dh, 40h ; Clear DH and make sure CF is set if error 57 mov dl, [cs:di] 58 eSHL_IM dx, 2 ; shift from one byte to two 59 jz SHORT .error 59 60 60 61 ; 61 62 ; Test for COM port presence, write to and read from registers 62 63 ; 63 64 65 66 67 68 69 70 64 push dx 65 add dl, Serial_UART_lineControl 66 mov al, 9Ah 67 out dx, al 68 in al, dx 69 pop dx 70 cmp al, 9Ah 71 jne SHORT .nextPort 71 72 72 73 74 75 76 73 mov al, 0Ch 74 out dx, al 75 in al, dx 76 cmp al, 0Ch 77 jne SHORT .nextPort 77 78 78 79 ; … … 88 89 ; Note: hardware baud multipliers (2x, 4x, 8x) will impact the final baud rate and are not known at this level 89 90 ; 90 91 91 mov dh, 30h * 2 ; multiply by 2 since we are about to divide by 2 92 mov dl, [cs:di] ; restore single byte port address for scan 92 93 93 94 .nextBaud: 94 95 96 97 98 95 shr dh, 1 96 jz SHORT .nextPort 97 cmp dh, 6 ; skip from 6 to 4, to move from the top of the 9600 baud range 98 jne SHORT .testBaud ; to the bottom of the 115200 baud range 99 mov dh, 4 99 100 100 101 .testBaud: 101 102 102 call SerialServerScan_CheckForServer_PortAndBaudInDX 103 jc SHORT .nextBaud 103 104 104 105 .error: 105 106 ret 106 107 107 .scanPortAddresses: db SERIAL_COM7_IOADDRESS >> 2 108 db SERIAL_COM6_IOADDRESS >> 2 109 db SERIAL_COM5_IOADDRESS >> 2 110 db SERIAL_COM4_IOADDRESS >> 2 111 db SERIAL_COM3_IOADDRESS >> 2 112 db SERIAL_COM2_IOADDRESS >> 2 113 db SERIAL_COM1_IOADDRESS >> 2 114 db 0 108 .scanPortAddresses: 109 db SERIAL_COM7_IOADDRESS >> 2 110 db SERIAL_COM6_IOADDRESS >> 2 111 db SERIAL_COM5_IOADDRESS >> 2 112 db SERIAL_COM4_IOADDRESS >> 2 113 db SERIAL_COM3_IOADDRESS >> 2 114 db SERIAL_COM2_IOADDRESS >> 2 115 db SERIAL_COM1_IOADDRESS >> 2 116 db 0 115 117 116 118 … … 133 135 ;-------------------------------------------------------------------- 134 136 SerialServerScan_CheckForServer_PortAndBaudInDX: 135 136 137 138 139 140 137 push bp ; setup fake SerialServer_Command 138 push dx ; send port baud and rate, returned in inquire packet 139 ; (and possibly returned in the drive identification string) 140 push cx ; send number of sectors, and if it is on a scan or not 141 mov bl, SerialServer_Command_Inquire ; protocol command onto stack with bh 142 push bx 141 143 142 143 144 mov bp, sp 145 call SerialServer_SendReceive 144 146 145 146 147 148 147 pop bx 148 pop cx 149 pop dx 150 pop bp 149 151 150 152 ret 151 153
Note:
See TracChangeset
for help on using the changeset viewer.