; Handle the MuSampler Commands

                GET             hdr.Common

                AREA            |$Commands|, PIC, CODE

                EXPORT          Commands
                IMPORT          StopAllAudio
                IMPORT          AudioBufferSizeInLBA
                IMPORT          AudioBufferSize
                IMPORT          AudioLBAsToRead
                IMPORT          AudioBytesToRead
		IMPORT		CloseFile
		IMPORT		OpenFile
		IMPORT		CDSectorInfo

; R0 ==> Command string = filename
; R1 ==> Count of commands

Commands        =               "CDFaker_Mount", 0
                &               Mount
                =               1, 0, 2, 0
                &               MountSyntax
                &               MountHelp

                =               "CDFaker_Dismount", 0
                &               Dismount
                =               1, 0, 1, 0
                &               DismountSyntax
                &               DismountHelp

                =               "CDFaker_Drives", 0
                &               DrivesCmd
                =               0, 0, 1, 0
                &               DrivesSyntax
                &               DrivesHelp

                =               "CDFaker_LoadEmulation", 0
                &               LoadEm
                =               2, 0, 2, 0
                &               LoadEmSyntax
                &               LoadEmHelp

                =               "CDFaker_NoEmulation", 0
                &               NoEm
                =               1, 0, 1, 0
                &               NoEmSyntax
                &               NoEmHelp

                =               "CDFakerAudioBuffer", 0
                &               ConfAudioBuffer
                =               1, 0, 1, 64
                &               ConfAudioBufferSyntax
                &               ConfAudioBufferHelp

                =               "CDFakerAudioReadAhead", 0
                &               ConfAudioReadAhead
                =               1, 0, 1, 64
                &               ConfAudioReadAheadSyntax
                &               ConfAudioReadAheadHelp

                &               0

                ALIGN

MountHelp       =               "*", 27, 0, " mounts a new CD image file to the "
                =               "specified drive. If no file is specified the current "
                =               "image is remounted.", 13
                =               "If a CDPM (CD Performance Map) file is named "
                =               "it will be loaded for the specified drive", 13
MountSyntax     =               27, 1, " <drive> [<image file>]", 0

DismountHelp    =               "*", 27, 0, " dismounts the specified drive.", 13
DismountSyntax  =               27, 1, " <drive>", 0

DrivesHelp      =               "*", 27, 0, " sets the number of CD drives reported to CDFS.", 13
                =               "NOTE: This must not be used after CDFS has scanned for valid "
		=               "drives, it will return an error.", 13
                =               "Without a parameter it will list the fake CD SCSI IDs", 13
DrivesSyntax    =               27, 1, " [<drives>]", 0

LoadEmHelp      =               "*", 27, 0, " loads an emulation file for the specified drive.", 13
LoadEmSyntax    =               27, 1, " <drive> <emulation spec>", 0

NoEmHelp        =               "*", 27, 0, " disables emulation for the specified drive.", 13
NoEmSyntax      =               27, 1, " <drive>", 0

ConfAudioBufferHelp
                =               27, 10, 27, 0, " sets the CD-Audio buffer size, specified "
                =               " in sectors (2352 bytes/sector 75 sectors/second)", 13
ConfAudioBufferSyntax
                =               "Syntax: ", 27, 10, " "
ConfAudioBufferSyntax2
                =               "CDFakerAudioBuffer", 9, "<sectors>", 0

ConfAudioReadAheadHelp
                =               27, 10, 27, 0, " sets the number of sectors (2352 "
                =               "bytes/sector 75 sectors/second) to read when enough space is "
                =               "free in the audio buffer.  A lower value will read from the disc "
                =               "more often.", 13
ConfAudioReadAheadSyntax
                =               "Syntax: ", 27, 10, " "
ConfAudioReadAheadSyntax2
                =               "CDFakerReadAhead", 9, "<sectors>", 0

ConfAudioBuffer_Str
                =               "CDFakerAudioBuffer ", 0

ConfAudioReadAhead_Str
                =               "CDFakerAudioReadAhead ", 0
ALIGN


ConfAudioBuffer SAVE            "r0-r2"
                TEQ             r0, #0               ;print syntax?
                BEQ             ConfAudioBuffer_PrintSyntax
                TEQ             r0, #1               ;print value?
                BEQ             ConfAudioBuffer_PrintValue

                LDR             ws, [ws]
                MOV             r2, #1024            ;max value
                BL              ReadUnsigned
                BVS             ConfAudioBuffer_exit

                BL              StopAllAudio
                ADRL            r1, AudioBufferSizeInLBA
                STR             r2, [r1]
                MOV             r0, #2352
                MUL             r0, r2, r0
                ADRL            r1, AudioBufferSize
                STR             r0, [r1]
                SUBS            r0, r0, r0

ConfAudioBuffer_exit
                RETURN_ERR

ConfAudioBuffer_PrintSyntax
                ADRL            r0, ConfAudioBufferSyntax2
                SWI             XOS_Write0
                SWI             XOS_NewLine
                RETURN

ConfAudioBuffer_PrintValue
                ADR             r0, ConfAudioBuffer_Str
                SWI             XOS_Write0

                ADRL            r1, AudioBufferSizeInLBA
                LDR             r0, [r1]
                BL              DisplayValue
                RETURN


ConfAudioReadAhead SAVE            "r0-r2"
                TEQ             r0, #0               ;print syntax?
                BEQ             ConfAudioReadAhead_PrintSyntax
                TEQ             r0, #1               ;print value?
                BEQ             ConfAudioReadAhead_PrintValue

                LDR             ws, [ws]
                MOV             r2, #1024            ;max value
                BL              ReadUnsigned
                BVS             ConfAudioReadAhead_exit

                ADRL            r1, AudioBufferSizeInLBA
                LDR             r0, [r1]
                CMP             r2, r0               ;check its <= Buffer size
                BHI             ReadAheadInvalid

                BL              StopAllAudio
                ADRL            r1, AudioLBAsToRead
                STR             r2, [r1]
                MOV             r0, #2352
                MUL             r0, r2, r0
                ADRL            r1, AudioBytesToRead
                STR             r0, [r1]
                SUBS            r0, r0, r0           ;clear V

ConfAudioReadAhead_exit
                RETURN_ERR

ReadAheadInvalid
                MOV             r0, #&80000000
                ADDS            r0, r0, r0           ;set V
                MOV             r0, #2
                RETURN_ERR

ConfAudioReadAhead_PrintSyntax
                ADRL            r0, ConfAudioReadAheadSyntax2
                SWI             XOS_Write0
                SWI             XOS_NewLine
                RETURN

ConfAudioReadAhead_PrintValue
                ADRL            r0, ConfAudioReadAhead_Str
                SWI             XOS_Write0

                ADRL            r1, AudioLBAsToRead
                LDR             r0, [r1]
                BL              DisplayValue
                RETURN


ReadUnsigned    SAVE
                MOV             r1, r0
                MOV             r0, #10              ;base 10
                SWI             XOS_ReadUnsigned
                RETURN


DisplayValue    SAVE
                SUB             r13, r13, #8
                MOV             r1, r13
                MOV             r2, #8
                SWI             XOS_ConvertInteger2
                SWI             XOS_Write0
                ADD             r13, r13, #8
                SWI             XOS_NewLine
                RETURN


; Get a decimal number in the range 0..R2
;
; R0 ==> Command string
; R1 ==> Argument count
;
; On exit
;
; R0 ==> Updated
; R1 ==> Updated
; R2 ==> Number

GetDecimal      SAVE            "r3"
                MOV             r3, #0

GetDecimal1     LDRB            r4, [r0]
                TEQ             r4, #" "
                ADDEQ           r0, r0, #1
                BEQ             GetDecimal1

                CMP             r4, #"0"
                RSBHSS          lr, r4, #"9"

GetDecimal2     BGE             GetDecimal3
                RESTORE
                MOV             r0, #1 << 31         ;set V
                ADDS            r0, r0, r0
                ADR             r0, BadNumberMsg
                MOV             pc, lr

GetDecimal3     LDRB            r4, [r0], #1
                CMP             r4, #"0"
                RSBHSS          lr, r4, #"9"
                BLT             GetDecimal4

                SUB             r4, r4, #"0"
                ADD             r3, r3, r3, LSL #2
                ADD             r3, r4, r3, LSL #1
                B               GetDecimal3

GetDecimal4     CMP             r2, r3
                BLT             GetDecimal2
                MOV             r2, r3
                SUBS            r1, r1, #1
                RETURN

BadNumberMsg    MKERR           BadNumber

; R0  ==> Command tail
; R1  ==> Argument count
;
; On exit
;
; R10 ==> Drive block

GetDrive        SAVE            "r2"
                MOV             r2, #MaxDrive
                BL              GetDecimal
                MOVVC           lr,     #Drive_Size :AND: &00FF
                ORRVC           lr, lr, #Drive_Size :AND: &FF00
                ADRVC           r10, DriveBlock
                MLAVC           r10, r2, lr, r10
                RETURN_ERR

Drive_Block_Size DCD Drive_Size

; CDFaker_Mount <drive> [<filename>]

Mount           SAVE            "r0-r6, r10, ws"
                LDR             ws, [ws]
                BL              GetDrive
                BVS             MountX

                LDR             r2, [r10, #Drive_Flags]
                ORR             r2, r2, #Drive_DiscChanged
                STR             r2, [r10, #Drive_Flags]
                CMP             r1, #0
                BLE             MountX

		BL		StopAllAudio
; Clear track info
                ADD             r2, r10, #Drive_Tracks
                MOV             r1, #TrackInfo_Size*MaxTracks
                MOV             r3, #0
ClearTrack_Info_L1
                STR             r3, [r2], #4
                SUBS            r1, r1, #4
                BNE             ClearTrack_Info_L1

                STR             r3, [r10, #Drive_ImageType]

		MOV             r1, r0
	        BL              skipSPACES
                MOV             r5, r1        ; Save name ptr for later
; Keep a copy of the name
                ADD             r2, r10, #Drive_FilePath
Mount_L1        LDRB            r0, [r5], #1
                CMP             r0, #" "
                MOVLE           r0, #0
                STRB            r0, [r2], #1
                BGT             Mount_L1

                STRB            r0, [r2, #1]	;terminate the string
                ADD             r5, r10, #Drive_FilePath
Mount_L2	LDRB            r0, [r2, #-1]
		STRB		r0, [r2], #-1
		TEQ		r0, #"."
		BNE		Mount_L2
		MOV             r0, #0
		STRB            r0, [r2, #1]
		ADD		r2, r2, #2	; r2 points to filename
		STR		r2, [r10, #Drive_FileName]

; Check the type and existance of the file
CUEread
                MOV             r0, #21
		LDR             r1, [r10, #Drive_FileName]
		ADD             r4, r10, #Drive_FilePath
                SWI             XOS_File
                TEQ             r0, #1			;is it a file?
		BLNE		GenerateFileError	;NO
		BVS		MountX
                BIC             r2, r2, #&FF

                LDR             r3, [r10, #Drive_ImageType]
                TEQ             r3, #0
                BNE             Mount5
                LDR             r3, =CUE_FileType
                TEQ             r6, r3
                BEQ             ReadCUEfile

                LDR             r3, =ISO_FileType
                TEQ             r6, r3
                RESTORE         NE
                MOVNE           r0, #1 << 31         ;set V
                ADDNES          r0, r0, r0
                ADRVS           r0, BadTypeMsg
                MOVVS		pc, lr
Mount5
		MOV             r6, r4        ; and length

		LDR             r1, [r10, #Drive_FileName]
		BL		OpenFile
                BVS             MountX

; Check for CDPM file
                SUB             sp, sp, #4

                MOV             r0, #4
                MOV             r2, sp
                MOV             r3, #4
                SWI             XOS_GBPB	;read the first 4 bytes
		BL		CloseFile
                LDR             r1, [sp], #4	;r0=first 4 bytes
                LDR             r2, CDPM
                TEQ             r1, r2
                BNE             Mount2

; It's a CDPM file, so load it (R4 is still its length)
; Allocate space for new block
                MOV             r0, #6
                MOV             r3, r6
                DBF             "XOS_Module %0w, %3w\n"
                SWI             XOS_Module
                MOVVC           r0, #16
                MOVVC           r1, r5      ; File name
                MOVVC           r3, #0
                MOVVC           r6, r2      ; Save address
                DBF             "XOS_File %0w, %1s, %2w, %3w (r10 = %r10w)\n", VC
                SWIVC           XOS_File    ; load it

                LDRVC           r2, [r10, #Drive_Emulation]
                STRVC           r6, [r10, #Drive_Emulation]
                BVS             MountX
                
                TEQ             r2, #0
                MOVNE           r0, #7
                SWINE           XOS_Module                                
                B               MountX

; New image being opened

Mount2		BL              Force_CD_rescan
                DBF             "Drive at %r10w, handle is %2w\n"
		SUBS		r0, r0, r0			;clear V

MountX		STRVS		r0, [sp, #0]
		LDR		r1, [r10, #Drive_Flags]
		BICVS		r1, r1, #Drive_Mounted
		ORRVC		r1, r1, #Drive_Mounted
		STR		r1, [r10, #Drive_Flags]
	        RETURN

GenerateFileError
		SAVE		"r2"
		MOV		r2, r0
                MOV		r0, #19
                SWI		XOS_File		;generate error
		RETURN

; Identify all CD's, so we can allocate a SCSI ID to our drives.

Force_CD_rescan SAVE            "r0-r3,r7"
                MOV             r3, #2_11111111
                SUB             sp, sp, #20
                MOV             r0, #0
                STR             r0, [sp, #12]
                STR             r0, [sp, #16]
                MOV             r7, sp
Force_CD_rescan_L1
                AND             r0, r3, #2_111
                STR             r0, [sp, #0]
                MOV             r0, r3, LSR #3
                AND             r0, r0, #2_11
                STR             r0, [sp, #4]
                MOV             r0, r3, LSR #5
                AND             r0, r0, #2_111
                STR             r0, [sp, #8]
                SWI             XCD_Identify
                SUBS            r3, r3, #1
                BNE             Force_CD_rescan_L1
                ADD             sp, sp, #20
                RETURN

CDPM            =               "CDPM"

BadTypeMsg      MKERR           BadType

Dismount        SAVE            "r0-r1, r10, ws"
                LDR             ws, [ws]
                BL              GetDrive
                BVS             DismountX
		BL		StopAllAudio
DismountX       RETURN_ERR

DrivesCmd       SAVE            "r0-r2, ws"
                LDR             ws, [ws]

		TEQ		r1, #0			;any parameters?
		BEQ		DisplayDrives		;NO, display drives

                LDR             r2, Flags
                TST             r2, #CDFSSeen
                RESTORE         NE
                MOVNE           r0, #1 << 31         ;set V
                ADDNES          r0, r0, r0
                ADRVS           r0, CantChDrMsg
                MOVVS           pc, lr

                MOV             r2, #MaxDrive
                BL              GetDecimal
                STRVC           r2, Drives
                RETURN_ERR

DisplayDrives
                MOVVC           lr,     #Drive_Size :AND: &00FF
                ORRVC           lr, lr, #Drive_Size :AND: &FF00
                ADR             r1, DriveBlock
		MOV		r2, #0
		SWI		XOS_WriteS
		DCB "  #  ID:CARD:LUN",10,13,0
		ALIGN
DisplayDrives_L1
		SWI		XOS_WriteS
		DCB "CD",0
		ALIGN
		ADD		r0, r2, #"0"
		SWI		XOS_WriteC
		SWI		XOS_WriteI+":"
		SWI		XOS_WriteI+" "
                LDRB            r0, [r1, #Drive_ID]
                ADD		r0, r0, #"0"
		SWI		XOS_WriteC
		SWI		XOS_WriteI+":"
                LDRB            r0, [r1, #Drive_Card]
                ADD		r0, r0, #"0"
		SWI		XOS_WriteC
		SWI		XOS_WriteI+":"
                LDRB            r0, [r1, #Drive_LUN]
                ADD		r0, r0, #"0"
		SWI		XOS_WriteC
		SWI		XOS_NewLine
		ADD		r1, r1, #Drive_Size :AND: &00FF
                ADD             r1, r1, #Drive_Size :AND: &FF00

		ADD		r2, r2, #1
                LDR             r0, [r1, #Drive_ID]
		CMP		r0, #-1
		TEQNE		r2, #MaxDrive
		BNE		DisplayDrives_L1
		RETURN

CantChDrMsg     MKERR           CantChDr

LoadEm
NoEm            MOV             pc, lr

; JJA CUE file support
;Entry:
; stack = r0-r6, r10, ws

ReadCUEfile	SAVE            "r7-r9, r11"		;parse CUE file

		LDR             r1, [r10, #Drive_FileName]
		BL		OpenFile
                MOV             r9, r1			;r9=file handle
                TEQ             r1, #0			;did an error occur
                BEQ             CUEfileError

		LDR		r2, [r10, #Drive_BINFiles]
		TEQ		r2, #0			;any RMA allocated for CUE
		MOVEQ		r0, #6
		MOVEQ		r3, #SpaceForBINFilenames	;allocate space for CUE FILE filenames
		SWIEQ		XOS_Module
		BVS		CUEfileErrorExit
		MOV		r11, r2			;r11=BIN filenames pointer
		STR		r2, [r10, #Drive_BINFiles]

                MOV             r0, #6
                MOV             r3, #256
                SWI             XOS_Module		;claim some temp space
                BVS             CUEfileErrorExit
                MOV             r8, R2			;r8=temp space address

                ADD             r7, r10, #Drive_Tracks	;r7=track info table
                MOV             r6, #0			;r6=last track#
		STR		r6, [r10, #Drive_LastFILEOffset]	;track the current file offset within the CD
		STR		r6, [r10, #Drive_LastFILESize]
		STR		r6, [r10, #Drive_DiscUsed]
ReadCUEfile_L1
                BL              FileReadLine
                MOV             r1, r8
                ADR             r0, strFILE
                BL              strCMP
                BEQ             CUE_FILE

                ADR             r0, strTRACK
                BL              strCMP
                BEQ             CUE_TRACK

                ADR             r0, strINDEX
                BL              strCMP
                BEQ             CUE_INDEX

                LDRB            r0, [r8, #0]
                TEQ             r0, #0
                BNE             ReadCUEfile_L1

                MOV             r0, #7
                MOV             r2, r8
                SWI             XOS_Module

                MOV             r1, r9
                BL		CloseFile

                RESTORE
                B               CUEread


FILE_TOO_LONGerror
	        ADR             r0, FilePathMsg
                B               CUEfileErrorExit
FILETYPEerror
                ADR             r0, FILETYPEMsg
                B               CUEfileErrorExit
TRACKTYPEerror
                ADR             r0, TRACKTYPEMsg
                B               CUEfileErrorExit
CUEfileError
                ADR             r0, MountErrMsg
CUEfileErrorExit
                MOV             r1, r9
                BL		CloseFile

                MOV             r1, #1<<31
                ADDS            r1, r1, r1           ;set V
                RESTORE
                B               MountX


MountErrMsg     MKERR MountErr
TRACKTYPEMsg    MKERR TRACKTYPEErr
FILETYPEMsg     MKERR FILETYPEErr
FilePathMsg     MKERR FilePathErr
strFILE         = "FILE", 0
strTRACK        = "TRACK", 0
strINDEX        = "INDEX", 0
                ALIGN


;Entry:
; stack - r1
; r6 - track # if a TRACK command has been seen
; r7 - Drive_Tracks table
; r11 - pointer to buffer for filenames

CUE_FILE	STR		r11, [r10, #Drive_LastBINFile]	
		ADD             r1, r8, #4		;skip "FILE"
                BL              skipSPACES		;and any spaces after

		LDR		r4, [r10, #Drive_BINFiles]
		ADD		r4, r4, #SpaceForBINFilenames
		MOV		r2, r11

                LDRB            r0, [r1], #1
                TEQ             r0, #34			;is it quoted?
                BEQ             CUE_FILE_QUOTED_L1

CUE_FILE_L3     TEQ             r2, r4			;hit end of buffer?
                BEQ             FILE_TOO_LONGerror
                TEQ             r0, #"."		;replace . with /
                MOVEQ           r0, #"/"
                STRB            r0, [r2], #1
                TEQ             r0, #" "		;end of filename
                TEQNE           r0, #0			;handle syntax errors
                LDRNEB          r0, [r1], #1
                BNE             CUE_FILE_L3
                B               CUE_FILE_DONE

CUE_FILE_QUOTED_L1
                TEQ             r2, r4			;hit end of buffer?
                BEQ             FILE_TOO_LONGerror
                LDRB            r0, [r1], #1
                TEQ             r0, #"."		;replace . with /
                MOVEQ           r0, #"/"
		TEQ		r0, #" "
		MOVEQ		r0, #160		;replace SPACE with a hard-space
                TEQ             r0, #34			;have we hit ending quote?
                TEQNE           r0, #0			;handle syntax errors
                STRNEB          r0, [r2], #1
                BNE             CUE_FILE_QUOTED_L1

CUE_FILE_DONE
		MOV             r0, #0
                STRB            r0, [r2], #1		;terminate filename
		MOV		r11, r2

                BL              skipSPACES

                ADR             r0, strBINARY
                BL              strCMP               
                MOVEQ           r3, #Type_BINARY
                BEQ             CUE_TYPE_found

                ADR             r0, strMOTOROLA
                BL              strCMP               
                MOVEQ           r3, #Type_MOTOROLA
                BEQ             CUE_TYPE_found

                ADR             r0, strAIF
                BL              strCMP               
                MOVEQ           r3, #Type_AIF
                BEQ             CUE_TYPE_found

                ADR             r0, strWAV
                BL              strCMP               
                MOVEQ           r3, #Type_WAV
                BEQ             CUE_TYPE_found

                ADR             r0, strMP3
                BL              strCMP               
                MOVEQ           r3, #Type_MP3
                BEQ             CUE_TYPE_found

                B               FILETYPEerror

CUE_TYPE_found
		LDR		r0, [r10, #Drive_LastFILEOffset]
		LDR		r1, [r10, #Drive_LastFILESize]
		ADD		r0, r0, r1
		STR		r0, [r10, #Drive_LastFILEOffset]	
		STR             r3, [r10, #Drive_ImageType]

		MOV		r0, #13
		LDR		r1, [r10, #Drive_LastBINFile]	
		ADD		r4, r10, #Drive_FilePath
		SWI		XOS_File		;r4=file size
                TEQ             r0, #1			;is it a file?
		BLNE		GenerateFileError	;NO
		BVS		CUEfileErrorExit
		LDR		r0, [r10, #Drive_DiscUsed]
		ADD		r0, r0, r4
		STR		r0, [r10, #Drive_DiscUsed]	
                B               ReadCUEfile_L1

strBINARY       = "BINARY", 0
strMOTOROLA     = "MOTOROLA", 0
strAIF          = "AIF", 0
strWAV          = "WAV", 0
strMP3          = "MP3", 0
                ALIGN



CUE_TRACK
                MOV             r3, #256             ;r3=format
                MOV             r4, #0               ;r4=framesize

                ADD             r1, r8, #5
                BL              readVAL              ;r2=track#
                SUB             r2, r2, #1           ;correct track#
                CMP             r2, #99              ;is track# valid
                BCS             ReadCUEfile_L1       ;NO
                MOV             r6, r2               ;r6=track#
                BL              skipSPACES
                                                     ;get track type
                ADR             r0, strAUDIO
                BL              strCMP               
                MOVEQ           r3, #Type_AUDIO
                BEQ             CUE_TRACK_found

                ADR             r0, strCDG
                BL              strCMP               
                MOVEQ           r3, #Type_CDG
                BEQ             CUE_TRACK_found

                ADR             r0, strMODE1_2048
                BL              strCMP               
                MOVEQ           r3, #Type_MODE1_2048
                BEQ             CUE_TRACK_found

                ADR             r0, strMODE1_2352
                BL              strCMP               
                MOVEQ           r3, #Type_MODE1_2352
                BEQ             CUE_TRACK_found

                ADR             r0, strMODE2_2336
                BL              strCMP               
                MOVEQ           r3, #Type_MODE2_2336
                BEQ             CUE_TRACK_found

                ADR             r0, strMODE2_2352
                BL              strCMP               
                MOVEQ           r3, #Type_MODE2_2352
                BEQ             CUE_TRACK_found

                ADR             r0, strCDI_2336
                BL              strCMP               
                MOVEQ           r3, #Type_CDI_2336
                BEQ             CUE_TRACK_found

                ADR             r0, strCDI_2352
                BL              strCMP               
                MOVEQ           r3, #Type_CDI_2352
                BEQ             CUE_TRACK_found

                B               TRACKTYPEerror

	MACRO
$Label	DIV	$Div,$Top,$Bot,$Temp
$Label	MOV	$Temp,$Bot
	CMP	$Temp,$Top,LSR #1
90	MOVLS	$Temp,$Temp,LSL #1
	CMP	$Temp,$Top,LSR #1
	BLS	%b90
	MOV	$Div, #0
91	CMP	$Top,$Temp
	SUBCS	$Top,$Top,$Temp
	ADC	$Div,$Div,$Div
	MOV	$Temp,$Temp,LSR #1
	CMP	$Temp,$Bot
	BHS	%b91
	MEND

CUE_TRACK_found
                ADD             r2, r7, r6, LSL #TrackInfo_SHL
                STR             r3, [r2, #TrackInfo_DataType]	;data type
		LDR		r1, [r10, #Drive_LastBINFile]
                STR             r1, [r2, #TrackInfo_FileName]

;work out where we are within the full CD
		ADR		lr, CUEfileErrorExit
		SAVE		"r4-r9"
		MOV		r5, r3
		BL		CDSectorInfo		;r6=framesize

		MOV		r0, #13
		ADD		r4, r10, #Drive_FilePath
		SWI		XOS_File		;r4=file size
		BLNE		GenerateFileError	;NO
		RETURN		VS
		DIV             r1, r4, r6, r14		;r1=size in frames
		STR		r1, [r10, #Drive_LastFILESize]
		RESTORE
                B               ReadCUEfile_L1


strAUDIO        = "AUDIO", 0
strCDG          = "CDG", 0
strMODE1_2048   = "MODE1/2048", 0
strMODE1_2352   = "MODE1/2352", 0
strMODE2_2336   = "MODE2/2336", 0
strMODE2_2352   = "MODE2/2352", 0
strCDI_2336     = "CDI/2336", 0
strCDI_2352     = "CDI/2352", 0
                ALIGN

; Entry:
; r6 - track # if a TRACK command has been seen
; r7 - Drive_Tracks table
; r8 - temp block

CUE_INDEX
                TEQ             r6, #0			;do we know the track?
                BEQ             ReadCUEfile_L1		;NO, ignore

                ADD             r1, r8, #5		;skip "INDEX"
                BL              readVAL			;r2=index
                CMP             r2, #1			;subindex
                BNE             ReadCUEfile_L1		;YES, ignore

                BL              skipSPACES
                BL              readVAL
                MOV             r4, #&1100
                ADD             r4, r4, #&94		;75*60
                MUL             r3, r4, r2		;r3=index in frames

                ADD             r1, r1, #1		;skip ":"

                BL              readVAL
                MOV             r4, #75
                MLA             r3, r4, r2, r3

                ADD             r1, r1, #1		;skip ":"

                BL              readVAL
                ADD             r3, r3, r2

                ADD             r1, r7, r6, LSL #TrackInfo_SHL	;track info offset
		STR		r3, [r1, #TrackInfo_LocalOffset]
;work out the actual offset within the full CD
		LDR		r2, [r10, #Drive_LastFILEOffset]
		ADD		r3, r3, r2
                STR             r3, [r1, #TrackInfo_Offset]
                B               ReadCUEfile_L1


;Entry:
; r1 = string pointer
;
;Exit:
; r1 = updated string pointer
; r2 = value

readVAL         SAVE "r0, r3"
                MOV             r0, #10
                SWI             XOS_ReadUnsigned
                RETURN

;Entry:
; r1 = string pointer
;
;Exit:
; r1 = updated string pointer

skipSPACES      SAVE "r0"
skipSPACES_L1   LDRB            r0, [r1], #1
                TEQ             r0, #32              ;skip SPACES
                BEQ             skipSPACES_L1
                SUB             r1, r1, #1
                RETURN


;Entry:
; r0 = string1
; r1 = string2
;
;Exit:
; EQ - strings are the same
; NE - strings are different

strCMP          SAVE "r0-r3"
strCMP_L1
                LDRB            r2, [r0], #1
                LDRB            r3, [r1], #1
                CMP             r2, #33
                CMPCC           r3, #33
                BCC             strCMPEQ

                CMP             r2, r3
                BEQ             strCMP_L1
                RETURN
strCMPEQ        CMP             r2, r2
                RETURN

;Entry:
; r9 = file handle
; r8 = 256 byte temp buffer
FileReadLine    SAVE "r1-r3"
                MOV             r1, r8               ;r1=string ptr
FileReadLine_L1
                BL              FileBGET
		BCS		FileReadLineExit     ;EOF
                CMP             r0, #32              ;strip off spaces
                BLE             FileReadLine_L1
FileReadLine_L2
		MOV		lr, #"z"
                CMP             r0, #"a"
		CMPCS		lr, r0
                BICCS           r0, r0, #32          ;convert to uppercase
		CMP		r0, #32
		BCC		FileReadLineExit
                STRB            r0, [r1], #1
                BL              FileBGET
		BCC		FileReadLine_L2
FileReadLineExit
                SUBS            r0, r0, r0           ;terminate string and clear V
                STRB            r0, [r1], #1
                RETURN

FileBGET        MOV             r0, #0
                SAVE		"r0-r3"
                MOV             r0, #4               ;read from current ptr
                MOV             r1, r9
                MOV             r2, sp
                MOV             r3, #1
                SWI             XOS_GBPB
                RETURN
; ---

                END
