Skip to content

Instantly share code, notes, and snippets.

@PluMGMK
Created January 25, 2026 16:52
Show Gist options
  • Select an option

  • Save PluMGMK/c52dc4af1614419cc894cd1202115c1f to your computer and use it in GitHub Desktop.

Select an option

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
.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