################################# ## MB-02 technical description ## ################################# Contens: 1. ROM bios 2. FDC bios 3. BS-DOS services 4. Disk format specification (c) Busy soft, Index 20000531171000 ----------------------------------------------------------------------------- *** ROM-BIOS *** ROM-BIOS switches ram banks and disables writing to ram banks of MB-02. It allows calling program between ram banks without use of memory above #4000. Preview ~~~~~~~ call #3C98 ... switch to ROM bank, write disable (works in both bank) call #3C9A ... switch to DOS bank, write disable (works in both bank) call #3C9C ... switch to ROM bank, write enable (works in both bank) call #3C9E ... switch to DOS bank, write enable (works in both bank) call #3CA0 ... call from one bank to other bank (works in both bank) call #3CA2 ... set tape as actual medium (works in ROM bank only) call #3CA4 ... set disk as actual medium (works in ROM bank only) Detailed description of calls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bank switching calls: #3C98, #3C9A, #3C9C, #3C9E These callings works in both ram bank - ROM and DOS. It's strongly recomended do NOT use OUT instructions for ram switch because address and data of switching port is depended MB-02 versions. Interbank calling: call #3CA0 Use this "far call" CALL #3CA0 by this way: Program runs in DOS bank and it wants call any routine (for example #22AA to compute coordinates) to ROM bank. It is possible by this way: program: ... call #3CA0 dw #22AA ... The same way can be used if ROM bank is switched and program wants call any routine to DOS bank. After called routine finished, program will continue in its own bank. Bank switch in CALL #3CA0 do not change any registers nor flags, and it needs only 8 bytes memory on stack. SP must be above #4008. NOTE: Since RST #28 is redirected to address #3CA0 in DOS bank, then if program runs in DOS bank and it wants call program into ROM bank, it can do: ... rst #28 dw #22AA ... Redirection rom load-save routines between tape and disk: call #3CA2, #3CA4 Rom load-save routines (entry points #4C6 and #562) may work with classic tape by classic way, or they may work with disk. What device will be used, it's set by these two calls. It's particulary equivalent to '@' commands: Zero parameter means LOAD/SAVE commands redirected to tape and non-zero parameter means to disk. ----------------------------------------------------------------------------- *** FDC-BIOS *** All accesses to FDC controller are via this FDC-BIOS. Processor does not make hard-time operation, then you can use freezer or run some routine from IM2 while any disk operation is running. If you make some routine in IM2, then this routine CAN NOT: - use or modify any settings of FDC and DMA controllers - contains time-precision loops (because DMA makes slow down processor) - run longer than 5-10 ms (this is not so important) - switch MB-02 ram banks by any way - and all modified registers must be PUSHed and POPed of course :) All services of FDC-bios may be calling by RST #18 in DOS ram bank. Register A must contains number of service. Other registers can contain another parameters for the called service. Preview ~~~~~~~ #00: RESET ..... reset FDC controller #01: STATUS .... read status information #02: RESTORE ... move head to track 0 #03: SEEK ...... move head to track N #04: RDSEC ..... read sector #05: WRSEC ..... write sector #06: RDTRK ..... read track (raw-mode) #07: WRTRK ..... formatting track #08: RDADD ..... read sector identification #09: REZIM ..... set density #0C: AKTIVE .... turn on drive N #0D: PASIVE .... turn off all drives #0E: INFO ...... get information about drive #0F: SETMAX .... set maximal length of data transfer #10: SETMLT .... set multitasking routine #11: SETOFF .... set turn-off motor mode Detailed description of services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Number of service: Mnemotechnical name of service I: Register = value [input parameters] I: Register = value [output parameters] ...description of service... #00: RESET O: A=status Reset FDC controler. This is good to call before work with FDC bios at begin of application. #01: STATUS O: A=status Returns status only. Status is described below. #02: RESTORE O: A=status Move drive head into track 0. #03: SEEK I: D=track O: A=status Move drive head into track D. #04: RDSEC I: DE=physical number of sector, HL=address O: A=status Reading of sector DE into memory at address HL from disk. #05: WRSEC I: DE=physical number of sector, HL=address O: A=status Writing of sector DE from memory at address HL to disk. There is no need call service SEEK before RDSEC and WRSEC. If it is needed, RDSEC and WRSEC does seek automatically. #06: RDTRK I: D=track, bit 7,E=side, HL=address O: A=status Reading whole track into memory at address HL. This service reads intersector information too, CRC codes of sectors are not procesed. This service is not right for sector data reading. #07: WRTRK I: D=track, bit 7,E=side, HL=address O: A=status Formatting track. HL is begin of formatting sequence for used FDC controller (usually WD2797). #08: RDADD I: D=track, bit 7,E=side, HL=address O: A=status Read sector identification. Read into memory 4 bytes: number of track, side, number of sector and length of sector. For detailed description, see WD2797. There is no need call service SEEK before services #04-#08. If SEEK is needed, they does seek automatically. #09: REZIM I: E=0 pre DD, 1 pre HD, 2 pre ED, ... O: Z=ok, NZ=error Set of density in active drive. If NZ occured, disk drive does not support this density. #0C: AKTIVE I: E=number of drive O: A=result Turn on drive E and turn off all other drives (if some of them was active). Results may be: 0 ... unknown disk ..... disk drive does not exist 1 ... disk not ready ... disk drive does not contains diskette 2 ... disk activated ... succesful, diskette was not changed 3 ... disk activated ... succesful, diskette may be changed If 0 or 1 occured, no drive will be active. #0D: PASIVE Turn off all disk drives. #0E: INFO I: E=number of disk drive O: DE=information about disk drive This service returns these informations: D = number of tracks E = supported densities bit 0 = 1 ... DD bit 1 = 1 ... HD bit 2 = 1 ... ED If disk drive does not exist, DE will be set to 0. #0F: SETMAX I: BC=maximal length of data movement This service sets maximal number of bytes for DMA operations. This service is not important for user applications. #10: SETMLT I: HL=multitasking routine address (or 0 if no multitasking) Since DMA does data transfer between memory and FDC controller, another machine code program may run while this data transfer is running. HL contains address of routine called on begin of all DMA transfers. DMA transfers are used in services RDSEC and WRSEC. If you want run some routine while sector is reading, writing, then this routine CAN NOT (the same rules as IM2 routine): - modify any settings of FDC and DMA controllers - contains time-precision loops (because DMA makes slow down processor) - run longer than 5-10 ms (this is not so important) - switch MB-02 ram banks by any way Routine may change any registers and must end by classic RET. #11: SETOFF I: E=turn-off motors mode If E=0 then PASIVE will turn off whole disk drive (enable and motor). If E=255 then PASIVE will turn off only enable of disk drive. In this case, motor will be continue running. This is useful if you want access two disk drives in short time intervals, then you must not wait for starting of disk drive motor. ----------------------------------------------------------------------------- Description of physical number of sector: bit 0-7,D ... track bit 7,E ... side (head) bit 0-6,E ... number of sector on track D Description of status byte: Bit Name of event Posibble situation Services 0 ... time out ............. service works too long ... [#04-#05] 1 ... disk not ready ..... diskette is not in drive ... [#04-#08] 2 ... lost data ................ DMA transfer error ... [#04-#08] 2 ... track 0 ............. Disk head is on track 0 ... [#00-#03] 3 ... CRC error .......... reading is not succesful ... [#04] 4 ... record not found ......... disk not formatted ... [#04,#05,#08] 4 ... seek error ... drive do not have track 0 (?!) ... [#02] 5 ... break ....... Q+W was pressed in DMA transfer ... [#04-#08] 6 ... write protect ... Diskette is write protected ... [#00-#02,#03,#05,#07] 7 ... not ready ......... cannot turn on disk drive ... [#04-#08] Bit is set if the event was occured. ------------------------------------------------------------------------------ *** BS-DOS Services *** All services of BS-DOS may be calling by RST #20 in DOS ram bank. Register A must contains number of service. Other registers can contain another parameters for the called service. Preview ~~~~~~~ #00: GETVER ...... get version number of BS-DOS #01: DISP ........ print one character #02: ENTER ....... move cursor to next line #03: TAB ......... move cursor to column N #04: TXXT ........ print text #05: DEC8X ....... print 8-bit number #06: DEC16X ...... print 16-bit number #07: DEC32X ...... print 32-bit number #08: DEC32 ....... 32-bit decrement #09: INC32 ....... 32-bit increment #0A: ADD32 ....... 32-bit addition #0B: SUB32 ....... 32-bit substraction #0C: SDDX ........ print mode #0D: BEEP ........ sound signal #0E: PREVODX ..... sector number conversion #0F: HOWSEC ...... file length conversion #10: KUKNI * ..... actualize internal cache #11: KUINI * ..... actualize internal cache with cache reset #12: GETCST * .... get current path #13: SETDRV ...... set disk drive #14: SETDIR * .... set directory #15: SETLCX * .... set load-cursor #16: GETSUB * .... get directory entry #18: KOLKOX * .... get directory lenght #19: SEASX * ..... searching file by name and type #1A: SEADX * ..... searching directory by name #1B: OWSUB * ..... owerwrite directory item #1E: KILLX ....... reset internal cache #1F: FREEX * ..... get free space #20: EMM562 * .... call #0562 emulation #21: EMM4C6 * .... call #04C6 emulation #22: LOA1X * ..... load a (part of) file #23: LOA2X * ..... load a (part of) file #24: VERIX * ..... verify a (part of) file #25: SAVEX * ..... save a (part of) file #26: CREATX * .... create new file #27: UTRASX * .... repack directory #28: ERASEX * .... erase file/directory #29: ERASIX * .... erase more files #2A: MOVEXX * .... move file/directory #2B: MOVEIX * .... move more files #2C: CATX * ...... catalogue of directory #2D: SEAXXX * .... searching substring in names #2E: CATXD * ..... cataloque of directory on another disk #2F: SEAXXD * .... searching substring on another disk #30: START ....... initialization after boot #31: BASIC ....... extended basic interpreter #32: FUNKC ....... extended DEF FN interpreter #33: FORMX * ..... quick format #34: MESSX ....... print text as system message #35: SDMSX ....... redirect error and info messages #36: UNERAX * .... unerase file/directory #37: UNERIX * .... unerase more files Services marked with '*' return carry flag by this way: If CY is set then service happened successfully, if CY is reset then an error occured (user did 'abort' probably). Some services want and/or return 32-bit value. This value is always in DE,HL registers, D is highest byte and L is lowest byte: DEHL Value = 256^3*D + 256^2*E + 256^1*H + 256^0*L Detailed description of services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Number of service: Mnemotechnical name of service ['*'] I: Register = value [input parameters] I: Register = value [output parameters] ...description of service... #00: GETVER O: BC=version of DOS (this manual is for version 308) IX=address of small data buffer used by #35:SDMSX #01: DISP I: E=character to print DOS internal PRINT routine, independent of RST #10 in basic rom. Cursor position is system variables XXX and YYY, actual used attribute is in system variable COLOR. This service do not support any control codes like CR,LF... Do not support scroll too. Output may be redirected into memory by SDDX service. Then XXX,YYY mean address of character storing in memory. Redirection is usable for services #04-#07. #02: ENTER Move print cursor to begin of next line. Rest of old line is filled by spaces. #03: TAB I: E=number of column Printing spaces while print-cursor is not on column E. #04: TXXT I: HL=begin of text Print text. Text must be ended by #00. #05: DEC8X I: E=value, C=character for left zeros Print 8-bit number. If you want left-justify, then C must be 0, if you right-justify, then C must be #20. For print one character, DISP is called. #06: DEC16X I: HL=value, C=character for left zeros Print 16-bit value. C is the same as in DEC8X. #07: DEC32X I: DEHL=value, C=character for left zeros, B=maximal length of number Print 32-bit value. C is the same as in DEC8X, B is maximal count of character from right of printed number. B must be no longer than 10. #08: DEC32 I: DEHL O: DEHL = DEHL-1 #09: INC32 I: DEHL O: DEHO = DEHL+1 #0A: ADD32 I: DEHL,BC O: DEHL = DEHL+BC #0B: SUB32 I: DEHL,BC O: DEHL = DEHL-BC This four services XXX32 handles 32-bit arithmetic. #0C: SDDX I: E=print mode This service says how DISP will be printed characters. E=0...DISP will be printed characters into screen. XXX and YYY is print position, COLOR is attribute of printed character. E=1...DISP will be printed characters into memory. XXX,YYY is address (XXX=low,YYY=high byte). COLOR has no meaning. #0D: BEEP Some like as BEEP basic command, but uses AY-3-8912 for no change border. #0E: PREVODX I: HL=logical number of sector, E=sector per track O: HL=DE=physical number of sector Sector number conversion. Physical number of sector see in FDC bios part. #0F: HOWSEC I: DEHL=length of file O: BC=number of sectors if Z, overflow if NZ Computing number of needed sector on disk for file with length DEHL. If file needs more than 65535 sectors, overflow occured. Note, 1 sector = 1024 bytes. Usable for parameter E if you want procees whole file by services #22-#25. #10: KUKNI * Checks diskette into disk drive and actualizes internal cache memories. #11: KUINI * Reset internal CACHE memories and reread all disk system sctructures. This is the same as calling #1E:KILLX and then #10:KUKNI. #12: GETCST * O: D=actual directory, E=actual disk, HL=load-cursor (actual file) Get actual path. #13: SETDRV I: E=number of disk drive Set actual drive. Does not try read diskette into selected disk immediatelly. #14: SETDIR * I: E=number of directory Set actual directory on diskette in actual disk drive. #15: SETLCX * I: BC=new load-cursor Set actual load-cursor. This is like rewing a virtual tape into file BC. #16: GETSUB * I: BC=number of file (load-cursor), IX=address of 32 byte buffer O: NZ = succesfull (directory item exist), Z = invalid directory item Get directory entry BC from actual directory and write it to buffer. #18: KOLKOX * O: DE=directory items Returns how many directory items are in actual directory. #19: SEASX * I: HL=address of 10 character string, E=type of file O: NZ = file not found, Z = file found successfully Searching file by filename and type of file. Filename is 10 characters long and must be match exactly. Filetype is very know number from basic: 0=basic, 1=number array, 2=character array, 3=bytes. If E is 255 then any filetype matches. This service searchs file from actual position of load-cursor to end of directory and then from begin of directory to actual position of load-cursor. If file found, load-cursor will be set to this file and searching is stopped immediatelly. #1A: SEADX * I: HL=address of 10 character string O: NZ = directory not found, Z = found and A = number of directory Searching directory by name. Name of directory is 10 characters long and must be match exactly. This service searchs directory from actual directory to end of directories (directory 255) and then from begin of directories (directory 0) to actual directory. If directory found, then A is set to this directory. #1B: OWSUB * I: HL=number of file, IX=new directory item Overwrite directory entry. If entry HL does not exist, nothing occured. This service is usable for renaming of files, setting another start address, change date, time and type of file. Warning ! Use this service carefuly because you can damage data integrity on disk (for example if you change length of body). The best using of this service is: First of all call GETSUB for get directory entry, then make some modification what you want and then store this entry into disk by this service OWSUB. #1E: KILLX Reset internal cache of disk. This service is needed if you change data on disk by another way as DOS services. For example, if you write some system structure sectors (boot,fat,directory) by FDC-bios services, DOS do not know what data is changed. #1F: FREEX * O: DEHL=free space ondisk in bytes, BC=in sectors Get free space on diskette in actual disk drive. DEHL=1024*BC #20: EMM562 * #21: EMM4C6 * These services are called for handle of tape routines #562 and #4C6 by using services #22-#26. #22: LOA1X * #23: LOA2X * #24: VERIX * #25: SAVEX * I: HL=number of file in actual directory, IX=address of memory, BC=beginning sector of file, E=number of processed sectors O: CY=1 ... all ok (maybe after user reply) CY=0 ... fail or user cancel These services loads, verifies and saves data from/to memory address IX to/from file sectors BC,BC+1,BC+2...BC+E. BC+E must not exceed total number of sectors of file. If lenght of file is not dividable by 1024, LOA1X loads only valid bytes from last sector, LOA2X loads all last sector. If you want procees whole file, you can use service HOWSEC to describe number of sectors. If VERIX detects any difference between file and memory, standart error message will be displayed. There are first, last and number of different bytes in message. #26: CREATX * I: IX=address of 32-bytes directory entry O: HL=number of this new file Create file. Directory entry must contain filled all information of file but first sector of file. This service writes system sctructures only, data sectors of file must be written by service SAVEX. #27: UTRASX * Repack directory. Deletes empty directory entries (after deleting files). Warning: Unerase after this service is not possible. #28: ERASEX * I: BC=number of file Erase file BC. If BC=0 then erases all directory. #29: ERASIX * I: BC..HL=range of files Erase files from BC to HL. If BC=0 then erases all directory. This service is more more faster than calling #28:ERASEX for each file. #2A: MOVEXX * I: BC=number of file, E=destination directory Move file BC from actual directory to directory E. If E is actual directory then it moves file at the end of directory. BC=0 means swap actual directory and directory E. #2B: MOVEIX * I: BC..HL=range of files, E=destination directory Move files from BC to HL to actual directory. If E is actual directory then it moves files at the end of directory. #2C: CATX * I: BC=directory specification Print directory as CAT/COPY basic command. If B=1 then actual directory will be printed, if B=0 then directory C will be printed. Bit 0 of system variable OPTIO says erased items will be printed too. #2D: SEAXXX * I: DE=string address, BC=string length (max 10) Searching substring in file names as .SEARCH basic command. Bit 0 of system variable OPTIO says erased items will be assumed in matching. #2E: CATXD * I: BC=directory specification, L=disk drive The same as CATX but actual directory of disk in disk drive L will be printed. #2F: SEAXXD * I: DE=string address, BC=string length (max 10), L=disk drive The same as SEAXXX but diskette in disk drive L will be searched. #33: FORMX * Quick format. Erases all directories and files on disk. Unerase all information is possible. #34: MESSX I: HL=text address O: CY=result of user interaction (CY=retry/ok,NC=abort) Print text as system message and wait for ENTER or SPACE. Text must me no longer than 28 bytes and must be ended by bytes #00 and #C9. For example: DB 'blah-blah-blah',#00,#C9 #35: SDMSX I: HL=address of routine or zero Redirection of all error and info messages. You may make application and original design of bs-dos messages may be poor. You can create your own design of messages by writing routine for print messages. All data needed for it are described below. #36: UNERAX * I: BC=number of file Unerase file. If BC=0 then it unerases directory. Note: Disk has all information of file after erase this file too. Then unerase immediatelly after any erase is always successfull. Unerasing files in unerased directory is no automatically. #37: UNERIX * I: BC..HL=range of files Unerase files from BC to HL. If BC=0 then unerases directory. This service is more more faster than calling #36:UNERAX for each file. Print error user routine ~~~~~~~~~~~~~~~~~~~~~~~~ Service #00:GETVER returns buffer address into IX. This buffer contains: Offset + #80 ... message text ended #00 #C0 ... (word) physical number of sector #C2 ... number of sector into track (from physical number) #C3 ... message colour (attribute) If number of sector is 0 then it is only message (for example #34:MESSX) and all other data about sector are unisable. Routine must display error or info message and then wait for user input to determine two posibilities: RETRY/OK and CANCEL/ABORT. Output must be CY=1 for RETRY/OK or CY=0 for CANCEL/ABORT. Routine can use dos services #00 - #0F only and change all registers. BS-DOS system variables ~~~~~~~~~~~~~~~~~~~~~~~ #03E0 XXX ....... column or low byte of print position #03E1 YYY ....... row or high byte of print position #03E2 COLOR ..... used attributes for print characters #03E3 OPTIO ..... some flags #03EE DISK ...... actual disk (this is set by service SETDRV) OPTIO bits: bit 0 .... mode of catalogue printing and searching (used by #2C-#2F) 0 = only valid files 1 = deleted files too bit 1 .... begin of catalogue printing (used by #2C,#2E) 0 = from begin of directory (file 1) 1 = from actual position of load-cursor bit 7 .... reset internal chache before writing operations 0 = make reset 1 = do not make reset Another bits are unused but must be 0 for future compatibility. ------------------------------------------------------------------------------ *** DISK FORMAT *** BOOT sector ~~~~~~~~~~~ physical number: track 0, side 0, sector 1 logical number: 0 This sector contains: #00-#01 ... Jump to system loader (#18,#7E) #02 ....... not used, usually #80 #03 ....... byte #02 (MB-02 mark) #04-#05 ... number of track on disk (usually 80) #06-#07 ... number of sectors per track #08-#09 ... number of sides of disk (usually 2) #0A-#0B ... number of sectors per cluster (usually 1) #0C-#0D ... logical number of DIRS sector #0E-#0F ... number of FAT sectors FAT (usually 1 to 4) #10-#11 ... length of FAT (#400 * number of FAT sectors) #12-#13 ... logical number of first sector of first FAT #14-#16 ... logical number of first sector of second (backup) FAT #20 ....... byte #00 (MB-02 mark) #21-#24 ... date and time of disk formatting #25 ....... byte #00 (MB-02 mark) #26-#2F ... name of disk #30-#3F ... extension of name of disk MB-02 marks says if it is MB-02 disk. DIRS sector ~~~~~~~~~~~ This sector contains 256 items, each item contains following 4 bytes: #00 ....... identification #80 = valid items for existing directory any other = directory does not exist (usually #00) #01 ....... XOR of name of directory (for speed-up search) #02,#03 ... logical number of first sector of directory (bits 0-13 only) SUBS sectors (directories sectors) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ They contain 32 bytes items: #00 ....... identification #90 = file contains only head #A0 = file contains only body (headerless) #B0 = file contains head and body #80 = file contains no head nor body (it's not often) Another values means invalid directory item. #01-#04 ... date and time of file #05-#15 ... classic 17-byte tape header #16-#17 ... additional address of body #18-#1B ... length of body (#18=least, #1B=most significant byte) #1C ....... flagbyte of body #1D ....... attributtes of file #1E-#1F ... number of first sector of file 0th item in directory contains no any file but has special meaning: #00 ....... identification (usually #80) #01-#04 ... date and time of file #05 ....... number of up-directory in tree (but not only tree!) structure #06-#0f ... name of directory ($"name" command find it) #10-#1f ... extension of name of directory File alocation table ~~~~~~~~~~~~~~~~~~~~ FAT contains 16-bit items, each item specified one sectors on disk. Bit 15: 0 ... free space 1 ... not free space (used or error) 14: 0 ... last sector of file 1 ... not last sector 0-13: [bit14=0] ... number of bytes to end of file in this last sector [bit14=1] ... logical number of next sector of file If high byte (bits 8-15) is set to #FF, then meaning of low byte (bits 0-7) is different: #00 ... special sector (boot, system, back-up) #F? ... unusable sector: #FC - error [Formatter detected CRC error] #FD - error [Formatter detected Record mot found] #FE - sector not exist (2nd side of one-side disk) #FF - sector not exist (out of physical range of disk) ------------------------------------------------------------------------------