Тогда ой. Contiki, в лучшем случае.
Ну или какие-нибудь носители с быстрым обменом через DMA использовать, но все равно это будет медленно ИМХО.
А ещё есть статическое ОЗУ в картридже на 32 кб.Цитата:
оперативки же всего 128 кб.
Сега-программист gasega использует это ОЗУ, только на 64кб в своей техно-деме mode7. Но на 64кб оно есть в MegaEverdrive. У меня просто everdrive, там только 32 кб, и поэтому текстуры разбиты полосками.
(http://www.sega-16.com/forum/showthr...for-Genesis-MD)
---------- Post added at 01:41 ---------- Previous post was at 01:38 ----------
Видал в архиве public domain (где выложены все-все-все любительские поделки на мд) демку типа POST-загрузка. Инициализация железа. Прикольно смотрелось.
Помойка исходников, из которых можно попробовать надергать что-то полезное для *UZIX:
http://ftp.sunet.se/pub/usenet/ftp.u...ces.unix/index
http://ftp.sunet.se/pub/usenet/ftp.u....sources.unix/
Понятно, что их в принципе существенно больше чем одна, но мне понравилась эта: престарелые исходники (что для нас немаловажно), есть индекс по архивам.
Гы гы гы! Для тех кто мало знает про историю компов, скажу так - эта OS (и не токо эта но и cp/m unix rsx11 rt11 и т.д.) БЕЗ СТАНДАРТНОГО API для графики. А значит "показывать" особо нечего (в смысле ААА на youtube обзор не выложит так как не будет смотреться эффектно). Стандартное програмное обеспечение этой OS работает с телетайпом типа как - Teletype Model 33.
Еще архивы исходников ранних версий *NIX:
http://minnie.tuhs.org/cgi-bin/utree.pl
Нам будет близок Seventh Edition Unix, КМК
Открою тайну - в UNIX вообще нет "СТАНДАРТНОГО API для графики" :)
Есть абстракция видеодрайвера - фреймбуффер и есть консоли-терминалы.
Графические приложения либо работают через фреймбуфер, либо, чаще - через отдельный графический X-сервер.
Так что с этой стороны как раз всё нормально.
Что, The End ?
Проблема большая, что под программу пользователя - 16К. Максимум на 128 спеке
Разделяемых библиотек - тоже не предусмотрено.
Можно сделать всё это под пентеву - но тогда это будет "пентева-только" система.
Для 128 спека надо что-то иное выдумывать.
Да и контекст очень медленно щёлкается.
Ну или делать только для пентевы свою ось. Но тогда надо механизм запуска спекопрок продумывать.
Контекст будет переключаться быстро, если переключать целыми страницами по 64к, минимизировав межстраничные копирования. Есть куча клонов с расширенным ОЗУ, надо только добавить диспетчер по 64к (а во многих, где 4 диспетчера по 16к, и добавлять ничего не надо, просто будет 4 команды включения страницы 16+16+16+16 вместо одной 64). Когда это нас стала пугать необходимость доработки? Если бы мне в, скажем, 96-м году сказали "вот тебе Юникс, но надо 3 микросхемки добавить", эти микросхемки были бы добавлены в тот же день. В конце концов, тут паяльщиков 50 человек на каждого программиста, ваще проблемы не вижу.
запилить этот юзикс на спринтера, чтоли?! только, какая практическая от этого польза?! сомнительное это нынче удовольствие...
Sayman, на феню запили ;)
AHTuXPuCT, не, фени нету и не хочу "её".
совершенно нет. Не только-лишь юзикс можно на си наваять))Цитата:
Вообще-то я думал ты как раз за этим с С-компилерами связался.
феникс это обычный скорпоКай. без всяких излишеств. не интересная для меня железка.Цитата:
А напрасно. У нас тут есть живой автор, он бы диспетчер с большим окном и впилил бы.
Error404, если ты про включение страниц во все 4 окна проца, тогда: атм, evo, спринтер. про феникса не знаю, может тоже умеет. может ещё есть какие-то.
Sayman, еще эва есть :)
64k? а какой толк от него будет? прийдется пересылать блоки между страницами только через регистры процессора (которых галяк), ну или через тормознутый i/o... (и тогда надо будет иметь копию кода для этого i/o в каждой странице) или тогда надо будет лепить какой-то еще memory-memory "копировщик" кроме Z80 на шину...
64к это условно.
На Орионе например переключается только 60к (а верхние 4к "склеенные" для всех страниц). Такая же модель памяти была исходной у Кокса при написании FUZIX. Достаточно удобно получается. Учитывая, что Юзиксу надо в общей памяти максимум 1к ("общей памяти"), то окно может быть и до 63кб размером. При этом каждое переключение контекста - это ldir примерно 2х400 байт ОЗУ + сохранение/восстановление регистров ЦПУ. Несравнимо с ldir Nх16к (в случае если делать процессы больше 16к при окне диспетчера 16к).
Но даже если переключать 3 окна по 16к - нижние 48k (а верхние 16к - "склеенные", в них кстати можно разместить непереключаемые общие для всех процессов бинари, тот же libc частично, или эмулятор CP/M), то 48к на процесс - это и то очень прилично.
Удобство в том, что пофиг сколько у тебя окон и какой размер страниц. Например, в моей реализации с 60-к страницами без перекомпиляции прекрасно работают бинарники однатысяча девятьсот мохнатого года от 32к-страничного Юзикса. Т.е. у нас будет кросплатформенность (точнее крос-клоновость) "вопреки всему" :)
А ну так это другое совсем, это "максимальное адресуемое пространство для процесса", ясное дело чем жирнее оно тем проще писать прогу (уже обсосали 100 раз, факт что большенство алгоритмов в литературе и компиляторов в жизни не учитывают лимитов адресного пространства).
К стати тут уже движутся работы в направлении прикручивания link-ера поддерживающего overlays. https://github.com/EtchedPixels/FUZI...oc/SDCCBanking
Какой-нибудь прогресс?
Да никакой, уже более 30 лет :)
Запуск на Спектруме мультизадачной операционной системы изначально не возможен без аппаратных доработок и замены процессора на более быстрый. Ну не побежит дедушка Z80 так, как к примеру на FPGA:
http://zx-pk.ru/attachment.php?attac...8&d=1416954953
Т.к. начало поддержано не было (ссылка) дальнейшая работа над проектом была свернута. Так, что не видать здесь мультизадачной ОС еще н-нацать лет :biggrin:
Пилю printf на асме. Основная проблема, из-за которой встала работа - катастрофическая нехватка памяти. А львиная доля её приходится на printf() и scanf(). Надеюсь, за счет использования асма и упрощения формата хотя бы килобайта 4 выиграть. Думаю, это позволит продолжить работу над портированием, если "портаторы" не потеряют интерес к тому времени.
А он так или иначе нужен ведь, почему бы и в ядре не попользоваться тогда?
Как по мне дак совсем не обязательно такому куску как ЯДРО, уметь печатать и форматировать текст так круто как может printf() вполне себе элементарного get/put хватало бы в какую-нибудь виртуальную "консоль", а тут выходит вот такой пример (утрированный), есть грубо говоря 3 куска кода занимающих всю память, 1-й ядро, 2-й printf(), 3-й прога LS например... они как не крути всю память зажрали, если printf() часть ядра то ясное дело что для LS нет маневра, даже тогда если LS решит токо половину printf-a использовать... вот и вся логика.
А вообще со времен прочтения про modula2 для pdp11 пришло понимание того что надо "уметь" разбивать прогу любой длинны и сложности на куски размером с 1 страницу (для zx это 16kB), тогда можно будет имея пачку свободных страничек + какой-то рабочий буфер выполнять и код ядра и код задач несмотря на ограниченное адресное пространство.
---------- Post added at 05:45 ---------- Previous post was at 05:16 ----------
Я так понимаю что "некоторые" варианты pdp11, (такие как тот же f11 применявшийся в pdp11/23) работают в той же "скоростной категории" что и z80, просто потому что это все те же 5мкм и соответственно примерно равные частоты, а битность на скорость влияет не так сильно как частота и кэши. Так вот многозадачность там работает, в том плане что может сидеть там паралельно человек 5 и набивать текст ed-ом и потом, компилировать его и играть там в rogue... Про графику забудьте, даже в самых простых динамических играх типа manic miner 90% скорости процессора потраченно на графику, так что надо вешать к спектруму еще один Z80 + память (шото типа general sound) и пускать тогда уже unix на нем, такая идея обкатанна на acon bbc b с его tube интерфейсом и множеством видов "second processor"-ов.
Между тем, в мире появился первый человек, получающий за разработку FUZIX зарплату
https://github.com/EtchedPixels/FUZI...ment-105659998
А у меня появилось стойкое ощущение, что в ZX128 оно больше не влазит.
Переписывание процедур на асме у меня продвигается ОЧЕНЬ медленно. Но, думаю, в настоящее время, с появлением SDCC v.3.5 имеет смысл не ждать пока я что-нибудь "рожу", а попробовать собрать ОСь новым компилятором, плотность кода СУЩЕСТВЕННО выросла по сравнению с предыдущей версии.
Собрал на досуге последнюю версию. Алан там наворотил, и теперь изменена вся схема памяти: во-первых, используется только ОЗУ, во-вторых, используется экран в 0xC000. То есть переключаемые страницы используются для всего подряд - и экран в них, и код ядра, и пользовательские программы. Всё это безобразие собирается только sdcc со специальными патчами для возможности кросс-банковых CALL-ов.
Затея достаточно интересная, конечно - и отлаживаться можно на любом эмуляторе (результат компиляции - z80/sna-файл), и в железе никаких изменений не требуется. Правда вот из-за этих новшеств драйвер бетадиска теперь не работает, и файловую систему не подсунуть.
Не прошло и года...
В общем, недавно вспомнил, что обещался printf на асме забацать. Спешу порадовать, что printf`у быть! :)
Собственно, автомат написан, но сегодня не выложу, ибо код ещё очень грязен, и не весь формат, какой хотел, реализован.
Это не сама printf, а служебная функция для её реализации. Её параметры: адрес п/п печати символа, адрес управляющей строки, адрес начала списка аргументов.
Думаю нужно обсудить, до какой степени упростить функцию.
Что поддержано на сегодня:
- Печать строк (%s), символов (%c), чисел десятичных (%d,%i,%u), шестнадцатиричных (%x,%X) и восьмеричных (%o).
- Размеры чисел от байта до лонга, т.е. спецификаторы "l" и "hh"
- Печать незначащих нулей в старших разрядах - флаг "0"
- Печать "+" перед положительным числом - флаг "+"
На остальные спецификаторы стоят заглушки.
Решил отказаться от обработки полей и выравнивания.
Пока длина кода составляет 844 байта.
Какие будут соображения?
Я думал, чтобы знать сколько надо отступить от левой границы поля, надо знать длину выводимого текста заранее, а для этого нужно сначала вывести текст в буфер, посчитав символы, а только потом уже в поток. Ради ускорения я пишу так, что всё сразу выводится в поток. Для чисел расчитать заранее ещё можно, а для строки - нет. Или я не правильно прочёл описание формата.
всё заглохло? Очень странно, видел какую-то сборку под Эву (которую так и не смог запустить, увидел только мельком начало инициализаци и всё...), только так и не понял, почему не поддержан тектовый режим, 4 метра памяти и другие навороты? Опять таки, есть тс-конфа, но и она не поддержана.
Потому что нет особенного смысла поддерживать ОС, под которую нет софта, зато в ядре которой с периодичностью в месяц меняется ну просто всё.
Мы по быстрому убедились, что за пару недель можно неспешно портировать фузикс на zx (ну, в каком-то виде). Это знание теперь с нами и никуда не денется.
Мои патчи давно в апстриме и тоже никуда не денутся, Алан хоть на zx не упирает, но и поломанным несобирающимся тот тоже не лежит.
Вот будет реальная причина возобновить работу - TCP/IP стек с юникс сокетами, например - тогда будем посмотреть.
Подумал, если буду ждать, пока улучшу процедуру, то хрен знает, когда я её выложу. Поэтому выкладываю как есть. Опробована в приложениях для бризовского CLI2. Для использования в своих целях замените подпрограмму вывода символа "OUTCHR":
Сейчас процедура печатает в буфер, содержимое которого потом выводится средствами CLI2:Код:OUTCHR::
exx
bit 7,c ; charcounter > 127 ?
jr nz,OCHe
OUTCH: ld (de),a
inc de
inc c
OCHe: exx
ret
Код:EXIT: exx
push bc
inc de
ex de,hl
ld (hl),#0 ; ставим 0 в конце сформированной строки.
exx
ld hl,#buffer
ld a,#0x0e
call 0x8003 ; CLI2 printString
Процедура полностью. Формат исходника - SDCC/sdasz80
Код:unsigned int printfx(unsigned char* cmdstr,...) __naked
{cmdstr;
__asm
TheFlag .equ 1
TheNum .equ 2
TheSize .equ 3
TheType .equ 4
sz_l .equ 0
sz_hh .equ 1
sz_h .equ 2
sz_ll .equ 3
sz_j .equ 4
sz_z .equ 5
sz_t .equ 6
sz_L .equ 7
PRINTF::
LD (EXITT+1),SP
POP BC ; return addres
POP HL ; direct string addres
EXX
LD HL,#0
ADD HL,SP ; args ptr
LD BC,#0 ; C = char counter
LD DE,#buffer
EXX
PUSH HL
PUSH BC
MCICLE: PUSH HL
CALL RESET
POP HL
WCICLE: LD A,(HL)
OR A
JR Z,EXIT
CP #'%'
JR NZ,M3
inc hl
ld a,(hl)
cp #'%'
jr z,M3
M4: CALL ParseFormat
OR A
JR NZ,M1 ; что за спецификатор?
LD A,(HL) ; нераспознанный спецификатор печатается как обычный символ.
M3: CALL OUTCHR
INC HL
JR WCICLE
M1: INC HL
CP #TheType
JR Z,MCICLE
LD A,(HL)
JR M4
EXIT: exx
push bc
inc de
ex de,hl
ld (hl),#0
exx
ld hl,#buffer
ld a,#0x0e
call 0x8003
pop hl ; char counter
EXITT: LD SP,#0
RET
; parsing routines for PRINTF
ParseFormat::
; in: A = checking symbol.
PUSH HL
LD HL,#FlagL
LD D,H
LD E,L
LD BC,#5
CPIR
JR NZ,ChkNum ; found
DoFlags: LD BC,#FlagSbr
DO: OR A,A
SBC HL,DE
DEC HL
ADD HL,HL
ADD HL,BC
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
JP (HL)
ChkNum: LD HL,#NumL
LD D,H
LD E,L
LD BC,#10
CPIR
JR NZ,ChkSize
LD C,A
LD A,#TheNum
RET
ChkSize:
LD HL,#SztpL
LD D,H
LD E,L
LD BC,#6
CPIR
JR NZ,#ChkType
LD BC,#SizeSbr
JR DO
ChkType:
LD HL,#TypeL
LD D,H
LD E,L
LD BC,#7; 19
CPIR
JR NZ,ChkPoint
DoType:
LD BC,#TypeSbr
JR DO
ChkPoint:
XOR A,A
DoPresn:
DoStar:
RET
; service subroutines for PRINTF
I2D:: LD C,#0
LD DE,#10000
CALL CNT
LD DE,#1000
CALL CNT
LD DE,#100
CALL CNT
LD DE,#10
CALL CNT
LD A,L
CALL OUTNUM
RET
CNT: XOR A,A
CNTL: OR A,A
SBC HL,DE
JR C,CNT1
INC A
JR CNTL
CNT1: ADD HL,DE
CALL OUTNUM
RET
;-----------------------
GETWORD::
GETPTR::
EXX
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PUSH DE
EXX
POP DE
RET
;-----------------------
GETBYTE::
EXX
LD A,(HL)
INC HL
EXX
RET
OUTSTR::
LD A,(HL)
OR A
RET Z
CALL OUTCHR
INC HL
JR OUTSTR
OUTCHR::
exx
bit 7,c ; charcounter > 127 ?
jr nz,OCHe
OUTCH: ld (de),a
inc de
inc c
OCHe: exx
ret
OUTNUM::
PUSH HL
LD HL,#zero
OR A
JR Z,oNM1
SET 0,(HL)
JR oNM2
oNM1: BIT 0,(HL)
JR Z,oNMe
JR oNMo
oNM2: CP #0x0A
JR C,oNMo ; not HEX
BIT 2,(HL)
JR Z,oNM3 ; upper case HEX
ADD A,#32 ; lower case HEX
oNM3: ADD A,#7
oNMo: ADD A,#"0"
CALL OUTCHR
oNMe: POP HL
RET
RESET:: LD HL,#sizes
LD DE,#sizes+#1
LD BC,#12
LDIR
EX DE,HL
LD (HL),#6
RET
; обработка флагов
FlagSbr:
.dw doDefice
.dw doSign
.dw doSpc
.dw doOkto
.dw doZero
doDefice:
LD A,#TheFlag
LD (defice),A
POP HL
RET
doSign:
LD A,#1
LD (sign),A
LD A,#TheFlag
POP HL
RET
doSpc:
LD A,#TheFlag
LD (#space),A
POP HL
RET
doOkto:
LD A,#TheFlag
LD (#alter),A
POP HL
RET
doZero:
LD A,#TheFlag
LD (zero),A
POP HL
RET
SizeSbr:
.dw do_l
.dw do_h
.dw do_j
.dw do_z
.dw do_t
.dw do_L
do_l:
POP HL
INC HL
CP (HL)
JR NZ,do_l1
LD A,(sizes)
SET sz_ll,A
JR do_h1e
do_l1: DEC HL
LD A,(sizes)
SET sz_l,A
JR do_h1e
do_h:
POP HL
INC HL
CP (HL)
JR NZ,do_h1
LD A,(sizes)
SET sz_hh,A
JR do_h1e
do_h1: DEC HL
LD A,(sizes)
SET sz_h,A
do_h1e: LD (sizes),A
LD A,#TheSize
POP HL
RET
do_j:
LD A,(sizes)
SET sz_j,A
POP HL
JR do_h1e
do_z:
LD A,(sizes)
SET sz_z,A
JR do_h1e
do_t:
LD A,(sizes)
SET sz_t,A
JR do_h1e
do_L:
LD A,(sizes)
SET sz_L,A
JR do_h1e
TypeSbr:
.dw do_d
.dw do_d
.dw do_u
.dw do_x
.dw do_X
.dw do_c
.dw do_s
do_d:: CALL GETWORD
EX DE,HL
BIT 7,H
JR Z,do_dpl
LD DE,#0
EX DE,HL
OR A,A
SBC HL,DE
LD A,#'-'
CALL OUTCHR
JR do_d1
do_dpl:
LD A,(sign)
OR A,A
JR Z,do_d1
LD A,#'+'
CALL OUTCHR
do_d1: LD A,(zero)
LD B,A
CALL I2D
LD A,#TheType
POP HL
RET
do_u:: CALL GETWORD
EX DE,HL
JR do_d1
do_x:: LD A,(zero)
SET 2,A
LD (zero),A
do_X:: LD A,#0x30
CALL OUTCHR
LD A,#'x'
CALL OUTCHR
CALL GETWORD
LD A,(sizes)
BIT sz_l,A
JR Z,do_X1
EX DE,HL
CALL GETWORD
EX DE,HL
LD A,#7
LD B,A
LD (do_XB+1),A
JR do_XL1
do_X1: BIT sz_hh,A
JR Z,do_X2
LD A,#1
LD B,A
LD (do_XB+1),A
JR do_XL1
do_X2: LD A,#3
LD B,A
LD (do_XB+#1),A
do_XL1: LD C,#4
PUSH DE
do_XL2: SRL H
RR L
RR D
RR E
DEC C
JR NZ,do_XL2
DJNZ do_XL1
LD A,E
do_XAND: AND A,#15
CALL OUTNUM
do_XB: LD B,#15
do_XL3: POP DE
LD A,E
AND #15
CALL OUTNUM
DJNZ do_XL3
do_xe: LD A,#TheType
POP HL
RET
do_c:
CALL GETWORD
LD A,E
do_ce: CALL OUTCHR
JR do_xe
do_s: CALL GETPTR
EX DE,HL
JR do_ce
sizes: .db 0
large: .db 0
field: .db 0
size: .db 0
type: .db 0
defice: .db 0
sign: .db 0
plus: .db 0
space: .db 0
alter: .db 0
zero: .db 0
before: .db 0
after: .db 0
presi: .db 0 ; default 6.
chcount: .dw 0
FlagL: .ascii '-+ #0'
NumL: .ascii '0123456789'
TypeL: .ascii 'diuxXcs'
SztpL: .ascii "lhjztL"
buffer:
.ascii "0123456789012345678901234567890123456789012345678901234567890000"
.ascii "01234567890123456789012345678901234567890123456789012345678900001"
__endasm;
}