На PLI утилиты писали. А СПМ десятки Source файлов. Завтра найду. Хоть в сети, хоть у мя.
- - - Добавлено - - -
Недавно собрал под TASM СПП, БДОС ( как мя достали эти ассемблеры со своей лексикой). Отличия в 10 байт. Для Орион-128.
Вид для печати
DRI писали на PLI - и ОС (включая V3 и MPM) и утилиты, пускай и кой-где с ассемблерными вставками, вот тут исходники их есть:
http://www.cpm.z80.de/source.html
Все полностью ассемблерные варианты - это декомпиленные версии, в том что они компилируются в код значительно совпадающий с классическим BDOS включая его баги - ничего удивительного в этом нет, любую программу можно декомпилировать, затем компильнуть и оно будет совпадать.
А с каким дистрибутивом Ориона сравнивалось?
Странно, в исходнике оно при режиме прямого позиционирования вроде обходит проверку (где-то попадалось на глаза). Возможно не все проверки обходит, конечно, т.к. мои примерчики через прямое позиционирование что-то тоже не отработали.
Попробовал сегодня "бомбануть наудачу" и увеличил (прям виндой - в образе, HEX-редактором) в процедурах послед. чтения маску обслуживаемых экстентов на пару бит (т.е. в 4 раза), в итоге текстовый файл размером 670кб последовательным чтением (фукция BDOS 14h) после этих правок прочитался до конца (чего раньше не происходило, обламывалось на 512кб). Непонятно - нафига оно вообще сделано???
Так что можно попробовать плеером с последовательным чтением (т.е. тем что был ранее как я понимаю) проигрывание более крупных (чем 512кб) WAV - а вдруг на поправленной ОС проканает?
Запись больших файлов не проверял: смысл это делать есть только в эмуляторе (плагин то понятно пишет и читает - ему на баги старых CPM пофиг), но терпения уже нету ждать пока оно разродится. :)
Поправленный образ тут (для экспериментов, грузиться с него без каких-либо изменения в образе, пробовал эмулятором как Орионом-128, так и Орионом-ПРО):
https://drive.google.com/file/d/0B3S...ew?usp=sharing
Итого поменяны 3 ячейки (адреса от начала образа, т.е. считая и MBR), не помню после какой из этих правок заработало:
132AH : 1F->7F
157CH : 1F->7F
1597H : 0F->03
Вот как оно выглядит в исходнике:
Во вложении исходники CP/M (ассемблерные, т.е. декомпилированные, но декомпилировавший проделал гигантский труд по комментированию, весьма подробному), те фрагменты что я смотрел, с BDOS от Альтаир-ДОС совпадали (по крайне мере в части файловых операций).Код:;
; Check extents in (A) and (C). Set the zero flag if they
; are the same. The number of 16k chunks of disk space that
; the directory extent covers is expressad is (EXTMASK+1).
; No registers are modified.
;
SAMEXT: PUSH BC
PUSH AF
LD A,(EXTMASK) ;get extent mask and use it to
CPL ;to compare both extent numbers.
LD B,A ;save resulting mask here.
LD A,C ;mask first extent and save in (C).
AND B
LD C,A
POP AF ;now mask second extent and compare
AND B ;with the first one.
SUB C
AND 1FH ;(* only check buts 0-4 *) <--- 132AH
POP BC ;the zero flag is set if they are the same.
RET ;restore (BC) and return.
;
;
; Routine to close the current extent and open the next one
; for reading.
;
GETNEXT:XOR A
LD (CLOSEFLG),A ;clear close flag.
CALL CLOSEIT ;close this extent.
CALL CKFILPOS
RET Z ;not there???
LD HL,(PARAMS) ;get extent byte.
LD BC,12
ADD HL,BC
LD A,(HL) ;and increment it.
INC A
AND 1FH ;keep within range 0-31. <--- 157CH
LD (HL),A
JP Z,GTNEXT1 ;overflow?
LD B,A ;mask extent byte.
LD A,(EXTMASK)
AND B
LD HL,CLOSEFLG ;check close flag (0ffh is ok).
AND (HL)
JP Z,GTNEXT2 ;if zero, we must read in next extent.
JP GTNEXT3 ;else, it is already in memory.
GTNEXT1:LD BC,2 ;Point to the 's2' byte.
ADD HL,BC
INC (HL) ;and bump it.
LD A,(HL) ;too many extents?
AND 0FH ; <--- 1597H
JP Z,GTNEXT5 ;yes, set error code.
;
; Get here to open the next extent.
;
GTNEXT2:LD C,15 ;set to check first 15 bytes of fcb.
CALL FINDFST ;find the first one.
CALL CKFILPOS ;none available?
JP NZ,GTNEXT3
LD A,(RDWRTFLG) ;no extent present. Can we open an empty one?
INC A ;0ffh means reading (so not possible).
JP Z,GTNEXT5 ;or an error.
CALL GETEMPTY ;we are writing, get an empty entry.
CALL CKFILPOS ;none?
JP Z,GTNEXT5 ;error if true.
JP GTNEXT4 ;else we are almost done.
GTNEXT3:CALL OPENIT1 ;open this extent.
GTNEXT4:CALL STRDATA ;move in updated data (rec #, extent #, etc.)
XOR A ;clear status and return.
JP SETSTAT
;
; Error in extending the file. Too many extents were needed
; or not enough space on the disk.
;
GTNEXT5:CALL IOERR1 ;set error code, clear bit 7 of 's2'
JP SETS2B7 ;so this is not written on a close.
;
; Read a sequential file.
;
RDSEQ: LD A,1 ;set sequential access mode.
LD (MODE),A
RDSEQ1: LD A,0FFH ;don't allow reading unwritten space.
LD (RDWRTFLG),A
CALL STRDATA ;put rec# and ext# into fcb.
LD A,(SAVNREC) ;get next record to read.
LD HL,SAVNXT ;get number of records in extent.
CP (HL) ;within this extent?
JP C,RDSEQ2
CP 128 ;no. Is this extent fully used?
JP NZ,RDSEQ3 ;no. End-of-file.
CALL GETNEXT ;yes, open the next one.
XOR A ;reset next record to read.
LD (SAVNREC),A
LD A,(STATUS) ;check on open, successful?
OR A
JP NZ,RDSEQ3 ;no, error.
RDSEQ2: CALL COMBLK ;ok. compute block number to read.
CALL CHKBLK ;check it. Within bounds?
JP Z,RDSEQ3 ;no, error.
CALL LOGICAL ;convert (BLKNMBR) to logical sector (128 byte).
CALL TRKSEC1 ;set the track and sector for this block #.
CALL DOREAD ;and read it.
JP SETNREC ;and set the next record to be accessed.
;
; Read error occured. Set status and return.
;
RDSEQ3: JP IOERR1
;
Интересно, "пропатчил" рамдисковый проигрыватель и он в этом альтаире с использованием 14h прочитал весь файл 676Кб (c 21h не весь).
Да, в этом и вопрос: зачем авторы BDOS изначально сделали искусственное ограничение - переполнение счетчика экстентов файла не по заполнению всего байта (что даже и проверяется проще - тупо во флаге переполнения), а ограничили пятью битами? Я для перестраховки (и простоты патча) только до семи бит расширил - чтобы не трогать статус флага переполнения CY (и мало ли может где в другом месте они в старшем бите что-нить смотрят). Этот "странный" алгоритм как мне кажется возник вследствие того, что BDOS изначально писан на языке высокого уровня, причем языке достаточно абстрактном и при этом не особенно наглядном (в отличие от, к примеру, С).
Я так понимаю, эти куски абсолюно одинаковые во всех реализациях BDOS от 2.2, и их тупо по сигнатурам можно найти (как я и искал в альтаировском варианте) и попробовать поправить например в векторовских реализациях где есть ограничение в 512кб.
На счет неработающей 21h: таки да, похоже тоже надо патчить - надо тоже посмотреть в исходнике как оно там реализовано (сразу не полез, не люблю разбираться в битовых операциях на сдвигах, а их там есть).
- - - Добавлено - - -
В-общем, еще слазил я в проверки, которые делает ф. 21h. Образ диска с "ручными правками по живому" тут:
https://drive.google.com/file/d/0B3S...ew?usp=sharing
Вот что поменял чтобы и при произвольном доступе была маска количества экстентов 7 бит вместо 5 (т.е. макс. размер файла 2мб вместо 512кб):
поменял такие ячейки (адреса от начала образа, т.е. считая и MBR):
172CH : 1F -> 7F
172FH : 1F 1F 1F 1F E6 0F -> 07 07 00 00 E6 03
Вот как оно выглядит в исходнике:
Теперь наконец то я смог выполнить (ранее DED.COM обламывался с чтением файла на границе в 512кб) то, о чем ранее упоминал на вопрос от OrionExt "как залить образ не имея на РС дисковода":Код:;
; For random i/o, set the fcb for the desired record number
; based on the 'r0,r1,r2' bytes. These bytes in the fcb are
; used as follows:
;
; fcb+35 fcb+34 fcb+33
; | 'r-2' | 'r-1' | 'r-0' |
; |7 0 | 7 0 | 7 0|
; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0|
; | overflow | | extra | extent | record # |
; | ______________| |_extent|__number___|_____________|
; also 's2'
;
; extent -> расширяем на 2 бита (до 7 бит), extra -> соответственно уменьшаем с 4 до 2 бит.
;
; On entry, register (C) contains 0ffh if this is a read
; and thus we can not access unwritten disk space. Otherwise,
; another extent will be opened (for writing) if required.
;
POSITION: XOR A ;set random i/o flag.
LD (MODE),A
;
; Special entry (function #40). M/PM ?
;
POSITN1:PUSH BC ;save read/write flag.
LD HL,(PARAMS) ;get address of fcb.
EX DE,HL
LD HL,33 ;now get byte 'r0'.
ADD HL,DE
LD A,(HL)
AND 7FH ;keep bits 0-6 for the record number to access.
PUSH AF
LD A,(HL) ;now get bit 7 of 'r0' and bits 0-3 of 'r1'.
RLA
INC HL
LD A,(HL)
RLA
AND 1FH ;and save this in bits 0-4 of (C). <---- 172Ch : 1F -> 7F
LD C,A ;this is the extent byte.
LD A,(HL) ;now get the extra extent byte.
RRA ; RLCA <---- 172Fh
RRA ; RLCA
RRA ; NOP
RRA ; NOP
AND 0FH ; AND 3
LD B,A ;and save it in (B).
POP AF ;get record number back to (A).
INC HL ;check overflow byte 'r2'.
LD L,(HL)
INC L
DEC L
LD L,6 ;prepare for error.
JP NZ,POSITN5 ;out of disk space error.
LD HL,32 ;store record number into fcb.
ADD HL,DE
LD (HL),A
LD HL,12 ;and now check the extent byte.
ADD HL,DE
LD A,C
SUB (HL) ;same extent as before?
JP NZ,POSITN2
LD HL,14 ;yes, check extra extent byte 's2' also.
ADD HL,DE
LD A,B
SUB (HL)
AND 7FH
JP Z,POSITN3 ;same, we are almost done then.
;
; Get here when another extent is required.
;
на IDE диск (CF,SD) скидываем образ дискетки (800кб) и за одно действие посекторно копируем его целиком на дискетку (дискетка должна быть заранее форматирована на Орионе же, желательно на 80+ треков {форматерами SF.COM, F83.COM, и т.п.}, содержимое ее 80 первых треков затем перезаписывается из файла c более емкого CP/M-диска, например IDE, где лежит образ дискетки для заливки). Залил Орионом утилитой DED.COM образ с IDE на гибкий диск (эмулятором естественно), затем проверил под виндой подопытный образ диска с образцовым - совпало. :) А раньше не работало, т.к. DED читает при помощи ф.21h (так делалось для копирования файла в треки в случае единственного привода на всю система (дисковода) - меняя диски ручками, т.е. в древнючие времена для небогатых парней: DED умеет "вставьте источник"-"вставьте приемник", а когда дело идет на двух приводах, понятно, ничего не спрашивает, но по-прежнему читает файл-источник через ф.21h)
Это я пока не пробовал, а в предыдущем варианте выявились некая особенность поведения с hdd. Проблема выглядит примерно так: если записать на hdd подряд несколько больших файлов, то с некоторого момента (возможно если их суммарный объем превысит 2 Мб) вместо последних записанные файлов (которые могут быть хоть маленькие, хоть большие) дос читает нечто левое (похоже на фрагмент программы). Проблема именно в досе, плагин обратно из образа копирует все файлы правильно. С дискетой проблем нет, все равно туда только один "большой" файл влезает.
Круть. К осени я подключусь. Как фулл Орион соберу. Забодаем СР/М 2.2=)