Changeset 181 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src/Device/Serial
- Timestamp:
- Nov 13, 2011, 3:38:40 PM (13 years ago)
- google:author:
- krille_n_@hotmail.com
- Location:
- trunk/XTIDE_Universal_BIOS/Src/Device/Serial
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm
r179 r181 10 10 ; http://en.wikibooks.org/wiki/Serial_Programming 11 11 ; 12 12 13 13 SerialCommand_UART_base EQU 0 14 14 SerialCommand_UART_transmitByte EQU 0 15 15 SerialCommand_UART_receiveByte EQU 0 16 16 SerialCommand_UART_divisorLow EQU 0 17 ; Values for UART_divisorLow: 17 ; Values for UART_divisorLow: 18 18 ; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 3 = 38400, 2 = 57600, 1 = 115200 19 19 … … 23 23 ; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level 24 24 25 SerialCommand_UART_interruptEnable EQU 1 25 SerialCommand_UART_interruptEnable EQU 1 26 26 SerialCommand_UART_divisorHigh EQU 1 27 27 ; UART_divisorHigh is zero for all speeds including and above 1200 baud … … 31 31 32 32 SerialCommand_UART_lineControl EQU 3 33 33 34 34 SerialCommand_UART_modemControl EQU 4 35 35 … … 40 40 SerialCommand_UART_scratch EQU 7 41 41 42 SerialCommand_PackedPortAndBaud_StartingPort EQU 240h 42 SerialCommand_PackedPortAndBaud_StartingPort EQU 240h 43 43 SerialCommand_PackedPortAndBaud_PortMask EQU 0fch ; upper 6 bits - 240h through 438h 44 44 SerialCommand_PackedPortAndBaud_BaudMask EQU 3 ; lower 2 bits - 4 baud rates … … 48 48 SerialCommand_Protocol_Inquire EQU 0 49 49 SerialCommand_Protocol_Header EQU 0a0h 50 50 51 51 ;-------------------------------------------------------------------- 52 52 ; SerialCommand_OutputWithParameters … … 65 65 ; AL, BX, CX, DX, (ES:SI for data transfer commands) 66 66 ;-------------------------------------------------------------------- 67 68 67 ALIGN JUMP_ALIGN 69 68 SerialCommand_OutputWithParameters: 70 69 71 70 mov ah,(SerialCommand_Protocol_Header | SerialCommand_Protocol_Read) 72 71 73 72 mov al,[bp+IDEPACK.bCommand] 74 73 … … 78 77 cmp al,30h ; Write Sectors IDE command 79 78 jz .readOrWrite 80 79 81 80 ; all other commands return success 82 81 ; including function 0ech which should return drive information, this is handled with the identify functions 83 82 xor ah,ah ; also clears carry 84 83 ret 85 86 .readOrWrite: 84 85 .readOrWrite: 87 86 mov [bp+IDEPACK.bFeatures],ah ; store protocol command 88 89 mov dl, byte [d s:di+DPT.bSerialPortAndBaud]90 87 88 mov dl, byte [di+DPT.bSerialPortAndBaud] 89 91 90 ; fall-through 92 91 … … 94 93 ; SerialCommand_OutputWithParameters_DeviceInDL 95 94 ; Parameters: 96 ; AH: Protocol Command 95 ; AH: Protocol Command 97 96 ; DL: Packed I/O port and baud rate 98 97 ; ES:SI: Ptr to buffer (for data transfer commands) … … 103 102 ; Corrupts registers: 104 103 ; AL, BX, CX, DX, (ES:SI for data transfer commands) 105 ;-------------------------------------------------------------------- 104 ;-------------------------------------------------------------------- 106 105 SerialCommand_OutputWithParameters_DeviceInDL: 107 106 108 107 push si 109 108 push di … … 111 110 push es 112 111 113 ; 112 ; 114 113 ; Unpack I/O port and baud from DPT 115 114 ; Port to DX more or less for the remainder of the routine … … 117 116 ; 118 117 mov cl, dl 119 118 120 119 and cl, SerialCommand_PackedPortAndBaud_BaudMask 121 120 shl cl, 1 … … 125 124 126 125 and dl, SerialCommand_PackedPortAndBaud_PortMask 127 mov dh, 0 126 mov dh, 0 128 127 shl dx, 1 129 128 add dx, SerialCommand_PackedPortAndBaud_StartingPort … … 131 130 ; 132 131 ; Buffer is referenced through ES:DI throughout, since we need to store faster than we read 133 ; 132 ; 134 133 mov di,si 135 134 … … 138 137 ; 139 138 ; Command byte and sector count live at the top of the stack, pop/push are used to access 140 ; 139 ; 141 140 push ax 142 143 cld 141 142 ; cld ; Shouldn't be needed. DF has already been cleared (line 24, Int13h.asm) 144 143 145 144 ;---------------------------------------------------------------------- … … 147 146 ; Initialize UART 148 147 ; 149 ; We do this each time since DOS (at boot) or another program may have 148 ; We do this each time since DOS (at boot) or another program may have 150 149 ; decided to reprogram the UART 151 150 ; 152 151 push dx 153 152 154 153 mov al,83h 155 154 add dl,SerialCommand_UART_lineControl … … 167 166 mov al,047h 168 167 inc dx ; fifo 169 out dx,al 168 out dx,al 170 169 171 170 mov al,03h … … 192 191 push es ; save off real buffer location 193 192 push di 194 195 mov di,bp ; point to IDEREGS for command dispatch; 193 194 mov di,bp ; point to IDEREGS for command dispatch; 196 195 push ss 197 196 pop es 198 197 199 198 xor si,si ; initialize checksum for write 200 dec si 199 dec si 201 200 mov bp,si 202 201 203 202 mov bl,03h ; writing 3 words 204 203 205 204 call SerialCommand_WriteProtocol 206 205 … … 213 212 ; 214 213 ; Top of the read/write loop, one iteration per sector 215 ; 214 ; 216 215 .nextSector: 217 216 xor si,si ; initialize checksum for read or write … … 220 219 221 220 mov bx,0100h 222 221 223 222 shr ah,1 ; command byte, are we doing a write? 224 223 jnc .readSector 225 224 call SerialCommand_WriteProtocol 226 225 227 226 xor bx,bx 228 227 … … 230 229 mov cx,bx 231 230 inc cx 232 231 233 232 mov bl,dl ; setup bl with proper values for read loop (bh comes later) 234 233 … … 246 245 push cx 247 246 xor cx,cx 248 .readTimeoutLoop: 247 .readTimeoutLoop: 249 248 push dx 250 249 or dl,SerialCommand_UART_lineStatus … … 257 256 mov bh,1 258 257 call SerialCommand_WaitAndPoll_Init 259 cli 258 cli 260 259 .readTimeoutComplete: 261 260 mov bh,bl 262 261 or bh,SerialCommand_UART_lineStatus 263 262 264 263 pop cx 265 264 test dl,1 … … 271 270 ; Read Block (without interrupts, used when there is a FIFO, high speed) 272 271 ; 273 ; NOTE: This loop is very time sensitive. Literally, another instruction 272 ; NOTE: This loop is very time sensitive. Literally, another instruction 274 273 ; cannot be inserted into this loop without us falling behind at high 275 ; speed (460.8K baud) on a 4.77Mhz 8088, making it hard to receive 274 ; speed (460.8K baud) on a 4.77Mhz 8088, making it hard to receive 276 275 ; a full 512 byte block. 277 276 ; 278 .readLoop: 277 .readLoop: 278 stosw ; store word in caller's data buffer 279 279 280 add bp, ax ; update Fletcher's checksum 280 281 adc bp, 0 … … 282 283 adc si, 0 283 284 284 stosw ; store word in caller's data buffer 285 286 mov dl,bh 287 in al,dx 285 mov dl,bh 286 in al,dx 288 287 shr al,1 ; data ready (byte 1)? 289 mov dl,bl ; get ready to read data 288 mov dl,bl ; get ready to read data 290 289 jnc .readTimeout ; nope not ready, update timeouts 291 292 ; 290 291 ; 293 292 ; Entry point after initial timeout. We enter here so that the checksum word 294 293 ; is not stored (and is left in AX after the loop is complete). 295 ; 296 .readByte1Ready: 294 ; 295 .readByte1Ready: 297 296 in al, dx ; read data byte 1 298 297 299 298 mov ah, al ; store byte in ah for now 300 301 ; 302 ; note the placement of this reset of dl to bh, and that it is 303 ; before the return, which is assymetric with where this is done 304 ; above for byte 1. The value of dl is used by the timeout routine 305 ; to know which byte to return to (.read_byte1_ready or 299 300 ; 301 ; note the placement of this reset of dl to bh, and that it is 302 ; before the return, which is assymetric with where this is done 303 ; above for byte 1. The value of dl is used by the timeout routine 304 ; to know which byte to return to (.read_byte1_ready or 306 305 ; .read_byte2_ready) 307 306 ; 308 mov dl,bh 309 307 mov dl,bh 308 310 309 in al,dx 311 310 shr al,1 ; data ready (byte 2)? 312 311 jnc .readTimeout 313 .readByte2Ready: 314 mov dl,bl 312 .readByte2Ready: 313 mov dl,bl 315 314 in al, dx ; read data byte 2 316 315 317 316 xchg al, ah ; ah was holding byte 1, reverse byte order 318 317 319 318 loop .readLoop 320 319 320 sti ; interrupts back on ASAP, if we turned them off 321 321 322 ; 322 323 ; Compare checksums 323 ; 324 ; 324 325 xor bp,si 325 326 cmp ax,bp 326 327 jnz SerialCommand_OutputWithParameters_Error 327 328 328 sti ; interrupts back on ASAP, if we turned them off 329 329 330 330 ;---------------------------------------------------------------------- 331 ; 331 ; 332 332 ; Clear read buffer 333 333 ; 334 334 ; In case there are extra characters or an error in the FIFO, clear it out. 335 ; In theory the initialization of the UART registers above should have 335 ; In theory the initialization of the UART registers above should have 336 336 ; taken care of this, but I have seen cases where this is not true. 337 337 ; 338 338 .clearBuffer: 339 mov dl,bh 339 mov dl,bh 340 340 in al,dx 341 mov dl,bl 341 mov dl,bl 342 342 test al,08fh 343 343 jz .clearBufferComplete 344 344 shr al,1 345 in al,dx 345 in al,dx 346 346 jc .clearBuffer ; note CF from shr above 347 347 jmp SerialCommand_OutputWithParameters_Error 348 349 .clearBufferComplete: 348 349 .clearBufferComplete: 350 350 pop ax ; sector count and command byte 351 351 dec al ; decrememnt sector count 352 352 push ax ; save 353 353 jz SerialCommand_OutputWithParameters_ReturnCodeInALCF ; CF clear from .clearBuffer test above 354 354 355 355 cli ; interrupts back off for ACK byte to host 356 356 ; (host could start sending data immediately) 357 357 out dx,al ; ACK with next sector number 358 358 359 359 jmp .nextSector ; all is well, time for next sector 360 360 … … 363 363 ; Cleanup, error reporting, and exit 364 364 ; 365 366 ; 365 366 ; 367 367 ; Used in situations where a call is underway, such as with SerialCommand_WaitAndPoll 368 ; 368 ; 369 369 SerialCommand_OutputWithParameters_ErrorAndPop2Words: 370 370 pop ax 371 371 pop ax 372 372 373 SerialCommand_OutputWithParameters_Error: 373 SerialCommand_OutputWithParameters_Error: 374 stc 374 375 mov al,1 375 stc 376 377 SerialCommand_OutputWithParameters_ReturnCodeInALCF: 376 377 SerialCommand_OutputWithParameters_ReturnCodeInALCF: 378 sti 378 379 mov ah,al 379 sti380 380 381 381 pop bp ; recover ax from stack, throw away … … 398 398 ; Returns when desired UART_LineStatus bit is cleared 399 399 ; Jumps directly to error exit if timeout elapses (and cleans up stack) 400 ; Corrupts registers: 400 ; Corrupts registers: 401 401 ; CX, flags 402 402 ;-------------------------------------------------------------------- … … 404 404 SerialCommand_WaitAndPoll_SoftDelayTicks EQU 20 405 405 406 ALIGN JUMP_ALIGN 406 ALIGN JUMP_ALIGN 407 407 SerialCommand_WaitAndPoll_Init: 408 408 mov cl,SerialCommand_WaitAndPoll_SoftDelayTicks 409 409 call Timer_InitializeTimeoutWithTicksInCL 410 410 ; fall-through 411 411 412 412 SerialCommand_WaitAndPoll: 413 413 call Timer_SetCFifTimeout … … 422 422 jz SerialCommand_WaitAndPoll 423 423 ; fall-through 424 425 SerialCommand_WaitAndPoll_Done: 424 425 SerialCommand_WaitAndPoll_Done: 426 426 ret 427 427 … … 442 442 SerialCommand_WriteProtocol: 443 443 mov bh,20h 444 444 445 445 .writeLoop: 446 446 test bh,1 447 447 jnz SerialCommand_WaitAndPoll_Done 448 448 449 449 mov ax,[es:di] ; fetch next word 450 450 inc di 451 451 inc di 452 452 453 453 add bp,ax ; update checksum 454 454 adc bp,0 … … 458 458 .writeLoopChecksum: 459 459 call SerialCommand_WaitAndPoll_Init 460 460 461 461 out dx,al ; output first byte 462 462 463 463 call SerialCommand_WaitAndPoll 464 464 465 465 mov al,ah ; output second byte 466 466 out dx,al … … 468 468 dec bl 469 469 jnz .writeLoop 470 470 471 471 inc bh 472 472 473 473 mov ax,bp ; merge checksum for possible write (last loop) 474 xor ax,si 475 474 xor ax,si 475 476 476 jmp .writeLoopChecksum 477 477 … … 501 501 mov dx,[cs:bp+IDEVARS.wPortCtrl] 502 502 inc dx 503 dec dx 503 dec dx 504 504 jz SerialCommand_AutoSerial 505 505 506 506 ; fall-through 507 SerialCommand_IdentifyDeviceInDL_DriveInBH: 507 SerialCommand_IdentifyDeviceInDL_DriveInBH: 508 508 509 509 push bp ; setup fake IDEREGS_AND_INTPACK … … 516 516 mov bl,0a0h ; protocol command to ah and onto stack with bh 517 517 mov ah,bl 518 518 519 519 push bx 520 520 … … 524 524 525 525 pop bx 526 527 pop cx 526 527 pop cx 528 528 pop dx 529 529 530 530 pop bp 531 531 532 ; place packed port/baud in vendor area of packet, read by FinalizeDPT 533 mov byte [es:si+SerialCommand_IdentifyDevice_PackedPortAndBaud], dl 532 ; place packed port/baud in vendor area of packet, read by FinalizeDPT 533 mov byte [es:si+SerialCommand_IdentifyDevice_PackedPortAndBaud], dl 534 534 535 535 ret … … 540 540 ; 541 541 ; When the SerialAuto IDEVARS entry is used, scans the COM ports on the machine for a possible serial connection. 542 ; 543 542 ; 543 544 544 SerialCommand_ScanPortAddresses: db 0b8h, 0f8h, 0bch, 0bah, 0fah, 0beh, 0feh, 0 545 545 ; Corresponds to I/O port: 3f8, 2f8, 3e8, 2e8, 2f0, 3e0, 2e0, 260, 368, 268, 360, 270 546 546 ; COM Assignments: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 547 547 548 ALIGN JUMP_ALIGN 549 SerialCommand_AutoSerial: 548 ALIGN JUMP_ALIGN 549 SerialCommand_AutoSerial: 550 550 mov di,SerialCommand_ScanPortAddresses-1 551 551 552 552 .nextPort: 553 553 inc di ; load next port address 554 554 mov dl,[cs:di] 555 555 556 556 mov dh,0 ; shift from one byte to two 557 shl dx,1 558 shl dx,1 557 eSHL_IM dx, 2 559 558 jz .exitNotFound 560 559 561 560 ; 562 561 ; Test for COM port presence, write to and read from registers 563 ; 564 push dx 562 ; 563 push dx 565 564 add dl,SerialCommand_UART_lineControl 566 565 mov al, 09ah … … 569 568 pop dx 570 569 cmp al, 09ah 571 jnz .nextPort 570 jnz .nextPort 572 571 573 572 mov al, 0ch … … 579 578 ; 580 579 ; Pack into dl, baud rate starts at 0 581 ; 580 ; 582 581 add dx,-(SerialCommand_PackedPortAndBaud_StartingPort) 583 582 shr dx,1 584 583 585 584 jmp .testFirstBaud 586 585 587 586 ; 588 587 ; Walk through 4 possible baud rates 589 ; 590 .nextBaud: 588 ; 589 .nextBaud: 591 590 inc dx 592 591 test dl,3 593 592 jz .nextPort 594 595 .testFirstBaud: 593 594 .testFirstBaud: 596 595 call SerialCommand_IdentifyDeviceInDL_DriveInBH 597 596 jc .nextBaud 598 597 599 598 ret 600 599 601 600 .exitNotFound: 601 stc 602 602 mov ah,1 603 stc604 603 605 604 ret -
trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialDPT.asm
r179 r181 18 18 or byte [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE 19 19 mov al, byte [es:si+SerialCommand_IdentifyDevice_PackedPortAndBaud] 20 mov byte [d s:di+DPT.bSerialPortAndBaud], al20 mov byte [di+DPT.bSerialPortAndBaud], al 21 21 ret 22 22 23
Note:
See TracChangeset
for help on using the changeset viewer.