Created
January 25, 2026 16:52
-
-
Save PluMGMK/c52dc4af1614419cc894cd1202115c1f to your computer and use it in GitHub Desktop.
Check Q-Channel Info reported by DOS CD drive immediately after starting to play track
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .8086 | |
| .model tiny | |
| .code | |
| org 100h | |
| PlayReq struc | |
| bLen db ? | |
| bUnit db ? | |
| bCmd db ? | |
| wStatus dw ? | |
| _resd dq ? | |
| bAMode db ? ; addressing mode (RedBook / High Sierra) | |
| dwStart dd ? ; first sector | |
| dwSectors dd ? | |
| PlayReq ends | |
| IOCTLRW struc ; IOCTL read/write request | |
| bLen db ? ; 3 for read, 12 for write | |
| bUnit db ? | |
| bCmd db ? | |
| wStatus dw ? | |
| _resd dq ? | |
| _resd1 db ? ; media descriptor byte = 0 for MSCDEX | |
| wBufOff dw ? | |
| wBufSeg dw ? | |
| wCount dw ? | |
| _resd2 dw ? ; starting sector number = 0 for MSCDEX | |
| _resd3 dd ? ; volume ID = 0 for MSCDEX | |
| IOCTLRW ends | |
| sDiskInfo struc | |
| bCode db ? ; 10 for read | |
| bLTrack db ? | |
| bHTrack db ? | |
| dwLOut dd ? | |
| sDiskInfo ends | |
| sTnoInfo struc | |
| bCode db ? ; 11 for read | |
| bTrack db ? | |
| dwStart dd ? | |
| bCtlADR db ? | |
| sTnoInfo ends | |
| QInfo struc | |
| bCode db ? ; 12 for read | |
| bCtlADR db ? | |
| bTrack db ? | |
| bPoint db ? | |
| bMinute db ? | |
| bSecond db ? | |
| bFrame db ? | |
| _resd db ? ; zero | |
| bPMin db ? | |
| bPSec db ? | |
| bPFrame db ? | |
| QInfo ends | |
| DRVIDX equ 'F'-'A' ; change to try a different drive | |
| xor ax,ax | |
| mov cx,(size sDiskInfo + size sTnoInfo) shr 1 | |
| mov di,offset discbuf | |
| rep stosw | |
| mov ax,1510h | |
| mov cx,DRVIDX | |
| lea bx,ioctlinput | |
| mov [ioctlinput.bLen],size IOCTLRW | |
| mov [ioctlinput.bCmd],3 | |
| mov [ioctlinput.wBufOff],offset discbuf | |
| mov [ioctlinput.wBufSeg],cs | |
| mov [ioctlinput.wCount],size sDiskInfo | |
| mov [discbuf.bCode],10 | |
| int 2Fh | |
| ; play the TPLS intro track... | |
| mov al,53 | |
| cmp al,[discbuf.bHTrack] | |
| jna @F | |
| ; there aren't that many tracks there, try the first one... | |
| mov al,20 | |
| @@: mov [ioctlinput.wBufOff],offset trackbuf | |
| mov [ioctlinput.wCount],size sTnoInfo | |
| mov [trackbuf.bCode],11 | |
| mov [trackbuf.bTrack],al | |
| mov ax,1510h | |
| int 2Fh | |
| .386 | |
| mov eax,[trackbuf.dwStart] | |
| mov [play.bLen],size PlayReq | |
| mov [play.bCmd],84h ; PLAY AUDIO | |
| mov [play.bAMode],1 | |
| mov [play.dwStart],eax ; play from beginning of track | |
| mov [play.dwSectors],75 ; just one second, to get an idea | |
| mov ah,9 ; write to stdout | |
| lea dx,aboutto | |
| int 21h | |
| movzx ax,[trackbuf.bTrack] | |
| call prtdw | |
| mov ah,9 ; write to stdout | |
| lea dx,ofdisc | |
| int 21h | |
| mov ah,2 ; write character to stdout | |
| mov dl,DRVIDX+'A' | |
| int 21h | |
| mov ah,9 ; write to stdout | |
| lea dx,newline | |
| int 21h | |
| mov ax,1510h | |
| lea bx,play | |
| int 2Fh | |
| mov ax,1510h | |
| lea bx,ioctlinput | |
| mov [ioctlinput.wBufOff],offset buf | |
| mov [ioctlinput.wBufSeg],cs | |
| mov [ioctlinput.wCount],size QInfo | |
| mov [buf.bCode],12 | |
| int 2Fh | |
| ; print out the QChan info: | |
| mov ah,9 ; write to stdout | |
| lea dx,curposn | |
| int 21h | |
| mov al,[buf.bTrack] | |
| call prtxb ; track number is BCD for some reason (but not on DOSBox when using OGG-based images - go fig!) | |
| mov ah,2 ; write character to stdout | |
| mov dl,':' | |
| int 21h | |
| movzx ax,[buf.bMinute] | |
| call prtdw | |
| mov ah,2 ; write character to stdout | |
| mov dl,':' | |
| int 21h | |
| movzx ax,[buf.bSecond] | |
| call prtdw | |
| mov ah,2 ; write character to stdout | |
| mov dl,':' | |
| int 21h | |
| movzx ax,[buf.bFrame] | |
| call prtdw | |
| mov ah,9 ; write to stdout | |
| lea dx,newline | |
| int 21h | |
| ret | |
| ; Print decimal word | |
| ; In: AX, ES==CS | |
| ; Out: Nothing | |
| ; Kill: AX, BX, DX, DI | |
| ; | |
| dw 1 ; protect from division by zero | |
| pow10 dw 1,10,100,1000,10000 | |
| prtdw proc near | |
| cld | |
| lea di,pow10 | |
| @@: scasw | |
| jnb @B | |
| sub di,2 | |
| @@: xor dx,dx | |
| div word ptr es:[di-2] | |
| sub di,2 | |
| ; AL now contains the coefficient of the current power of ten | |
| mov bx,dx ; save the remainder | |
| call prtxn | |
| mov ax,bx ; get the remainder back | |
| cmp word ptr es:[di],1 | |
| ja @B | |
| ret | |
| prtdw endp | |
| ; Print hex nibble | |
| ; In: AL (low nibble) | |
| ; Out: Nothing | |
| ; Kill: AX, DL | |
| ; | |
| prtxn proc near | |
| cmp al, 10 | |
| jb not_asc | |
| add al, 'A' - '0' - 10 | |
| not_asc: | |
| add al, '0' | |
| mov ah,2 ; write character to stdout | |
| mov dl,al | |
| int 21h | |
| ret | |
| prtxn endp | |
| ; Print hex byte | |
| ; In: AL | |
| ; Out: Nothing | |
| ; Kill: AX, CL, DX | |
| ; | |
| prtxb proc near | |
| mov dh, al | |
| mov cl, 4 | |
| shr al, cl | |
| call prtxn | |
| mov al, dh | |
| and al, 0fh | |
| call prtxn | |
| ret | |
| prtxb endp | |
| .data | |
| aboutto db "About to play first second of track $" | |
| ofdisc db " of disc in drive $" | |
| newline db 0Dh,0Ah,"$" | |
| curposn db "Head position reported by drive immediately after command: $" | |
| .data? | |
| play PlayReq <?> | |
| ioctlinput IOCTLRW <?> | |
| discbuf sDiskInfo <?> | |
| trackbuf sTnoInfo <?> | |
| buf QInfo <?> | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment