С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
nzeemin(02.01.2023)
Осмотрел исходники процесса дисковода и винчестера. Там контроллер программируется в режиме DMA. Сами данные для команды:
f.spec: .byte 3, 12.*20+1, 2
Т.е. время шага равно 12 мс, время разгрузки головки 16 мс (1), время загрузки головки 2 мс (1) и режим DMA (бит 0 в последнем байте равен нулю). В режиме DMA задействуются сигналы DRQ, DACK, RD, WR - это уже надо смотреть схему, как это там реализовано. А так как объём буферного СОЗУ вроде бы только 2 КБайта, то за раз можно прочесть и записать максимум четыре сектора.
nzeemin(02.01.2023)
Titus, а как вы заполняете HR0/HR1 при обращении к регистрам эмуляции 174000..177677 ?
Код прерывания в BIOS для чтения сначала смотрит в HR0 и потом в HR1, для записи сначала в HR1 потом HR0.
Но отлаживая эмулятор, я понял что всегда надо писать адрес в HR0.
- - - Updated - - -
Alex_K, вы не разбирались с картой процессов в памяти? Если я правильно понимаю, она лежит по адресу 0x00217a и дальше. Хотелось бы понять что к чему, сделать отдельную вкладку со списком процессов в эмуляторе.
Не совсем понял вопрос, но вот то, что относится к этим регистрам:
Скрытый текст
Код:static UINT16 HR0 = 0, // Регистры MMU HALT-режима HR1 = 0, HR2 = 0, HR3 = 0, HR4 = 0, HR5 = 0, HR6 = 0, HR7 = 0; CPU_RgRdWProc[0x0280] = CPU_RdW_HR0; // Регистр HR0 (чтение) CPU_RgWrWProc[0x0280] = CPU_WrW_HR0; // Регистр HR0 CPU_RgRdWProc[0x0282] = CPU_RdW_HR1; // Регистр HR1 (чтение) CPU_RgWrWProc[0x0282] = CPU_WrW_HR1; // Регистр HR1 CPU_RgRdWProc[0x0284] = CPU_RdW_HR2; // Регистр HR2 (чтение) CPU_RgWrWProc[0x0284] = CPU_WrW_HR2; // Регистр HR2 CPU_RgRdWProc[0x0286] = CPU_RdW_HR3; // Регистр HR3 (чтение) CPU_RgWrWProc[0x0286] = CPU_WrW_HR3; // Регистр HR3 CPU_RgRdWProc[0x0288] = CPU_RdW_HR4; // Регистр HR4 (чтение) CPU_RgWrWProc[0x0288] = CPU_WrW_HR4; // Регистр HR4 CPU_RgRdWProc[0x028A] = CPU_RdW_HR5; // Регистр HR5 (чтение) CPU_RgWrWProc[0x028A] = CPU_WrW_HR5; // Регистр HR5 CPU_RgRdWProc[0x028C] = CPU_RdW_HR6; // Регистр HR6 (чтение) CPU_RgWrWProc[0x028C] = CPU_WrW_HR6; // Регистр HR6 CPU_RgRdWProc[0x028E] = CPU_RdW_HR7; // Регистр HR7 (чтение) CPU_RgWrWProc[0x028E] = CPU_WrW_HR7; // Регистр HR7 printf("HALT MMU: %03X, %03X, %03X, %03X, %03X, %03X, %03X, %03X\nUSER MMU: %03X, %03X, %03X, %03X, %03X, %03X, %03X, %03X\n", HR0 >> 4, HR1 >> 4, HR2 >> 4, HR3 >> 4, HR4 >> 4, HR5 >> 4, HR6 >> 4, HR7 >> 4, UR0 >> 4, UR1 >> 4, UR2 >> 4, UR3 >> 4, UR4 >> 4, UR5 >> 4, UR6 >> 4, UR7 >> 4); static UINT16 FASTC CPU_RdW_HR0(void) // HR0 { //printf("Read word from CPU register HR0 from location PC=0x%X\n", // (UINT16)CPU->l.PC); PPI_B |= 0x0002; // EF1 = 1 PPI_B |= 0x0001; // EF0 = 1 return(HR0); } static UINT16 FASTC CPU_RdW_HR1(void) // HR1 { //printf("Read word from CPU register HR1 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR1); } static UINT16 FASTC CPU_RdW_HR2(void) // HR2 { //printf("Read word from CPU register HR2 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR2); } static UINT16 FASTC CPU_RdW_HR3(void) // HR3 { //printf("Read word from CPU register HR3 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR3); } static UINT16 FASTC CPU_RdW_HR4(void) // HR4 { //printf("Read word from CPU register HR4 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR4); } static UINT16 FASTC CPU_RdW_HR5(void) // HR5 { //printf("Read word from CPU register HR5 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR5); } static UINT16 FASTC CPU_RdW_HR6(void) // HR6 { //printf("Read word from CPU register HR6 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR6); } static UINT16 FASTC CPU_RdW_HR7(void) // HR7 { //printf("Read word from CPU register HR7 from location PC=0x%X\n", // (UINT16)CPU->l.PC); return(HR7); } static void FASTC CPU_WrW_HR0(UINT16 Data) // [T] HR0 { //printf("Write word 0x%04X to CPU register HR0 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR0 = Data; return; } static void FASTC CPU_WrW_HR1(UINT16 Data) // [T] HR1 { //printf("Write word 0x%04X to CPU register HR1 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR1 = Data; return; } static void FASTC CPU_WrW_HR2(UINT16 Data) // [T] HR2 { //printf("Write word 0x%04X to CPU register HR2 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR2 = Data; SetMMU_Halt(2, Data); return; } static void FASTC CPU_WrW_HR3(UINT16 Data) // [T] HR3 { //printf("Write word 0x%04X to CPU register HR3 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR3 = Data; SetMMU_Halt(3, Data); return; } static void FASTC CPU_WrW_HR4(UINT16 Data) // [T] HR4 { //printf("Write word 0x%04X to CPU register HR4 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR4 = Data; SetMMU_Halt(4, Data); return; } static void FASTC CPU_WrW_HR5(UINT16 Data) // [T] HR5 { //printf("Write word 0x%04X to CPU register HR5 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR5 = Data; SetMMU_Halt(5, Data); return; } static void FASTC CPU_WrW_HR6(UINT16 Data) // [T] HR6 { //printf("Write word 0x%04X to CPU register HR6 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR6 = Data; SetMMU_Halt(6, Data); return; } static void FASTC CPU_WrW_HR7(UINT16 Data) // [T] HR7 { //printf("Write word 0x%04X to unrealized CPU register HR7 from location PC = 0x%X\n", // Data, (UINT16)CPU->l.PC); HR7 = Data; return; }[свернуть]
nzeemin(03.01.2023)
С этим не разбирался. Но на диске SOUZ-NEON_HD4_CLIB11_P16VPO_IMG.DSK есть виртуальный диск P16VP0.DSK, в нём программа, выводящая список процессов - PS.MAC.
Она небольшая:Скрытый текст
Код:.title processes listing .include "sy:p16mac" sbuf = 177566 start: mov pc, sp mov #str0, @#sbuf nop mov #str1, @#sbuf nop mfhlt #running sub #p.sp, r0 mov r0, runn mfhlt #pdptr mov r0, next 10$: inc num mov #freepr,r0 11$: mfhlt r0 cmp next, r0 beq 14$ tst r0 bne 11$ mov next, r0 call ttt mov #s.num, @#sbuf ;.print #s.num 14$: add #p.dsucc,next mfhlt next mov r0, next bne 10$ clr pc ttt: ;------------------------------------------------------------ mov r0, r3 ;desc. address mov #s.da+6,r4 mov #6, r5 call oct ;------------------------------------------------------------ mov num, r3 ;process number mov #s.num+2,r4 mov #2, r5 call dec0 ;------------------------------------------------------------ mov next, r0 ;CPU time add #p.tim1,r0 mfhlt r0 mov r0, r1 cmp runn, next bne 10$ mfhlt #c.tim1 add r0, r1 10$: clr r0 div #60., r0 mov r1, r3 mov #s.time+9.,r4 mov #2, r5 call dec movb #':, -(r4) mov r0, r1 beq 16$ clr r0 div #60., r0 mov r1, r3 mov #2, r5 call dec mov r0, r3 beq 20$ movb #'., -(r4) mov #2, r5 call dec br 24$ 16$: movb #'0, -(r4) movb #40, -(r4) 20$: movb #40, -(r4) movb #40, -(r4) movb #40, -(r4) 24$: ;------------------------------------------------------------ mov #16., r5 ; process name mov #s.name,r4 mov next, r1 add #p.name,r1 26$: mfhlt r1 cmpb r0, #40 blo 30$ ; ; cmpb #176, r0 ; bcs 30$ movb r0, (r4)+ dec r5 swab r0 cmpb r0, #40 blo 30$ ; ; cmpb #176, r0 ; bcs 30$ movb r0, (r4)+ tst (r1)+ sob r5, 26$ br 40$ 30$: movb #40, (r4)+ sob r5, 30$ ;------------------------------------------------------------ 40$: mov next, r0 ;priority add #p.pri, r0 mfhlt r0 mov #40, r1 mov r0, r3 bpl 45$ neg r3 mov #'-, r1 45$: mov #s.pri+6,r4 mov #5, r5 call oct0 movb r1, -(r4) ;------------------------------------------------------------ mov next, r0 ;process state cmp r0, runn bne 50$ mov #st.run,r0 br 60$ 50$: add #p.mask,r0 mfhlt r0 bit #m.run, r0 beq 51$ mov #st.wai,r0 br 60$ 51$: bit #m.tio, r0 beq 52$ mov #st.tim,r0 br 60$ 52$: tstb r0 beq 53$ mov #st.int,r0 br 60$ 53$: mov #st.io, r0 60$: mov #s.stat,r1 movb (r0)+, (r1)+ movb (r0)+, (r1)+ movb (r0)+, (r1)+ movb (r0)+, (r1)+ ;--------------------------------------------------------------------- mov next, r0 ;process memory size add #p.mem, r0 mfhlt r0 ; map addr clr low clr high mov r0, r1 beq 70$ ;no ram-map mov #4, r5 ;low mem 62$: mfhlt r1 com r0 63$: rol r0 beq 64$ adc low clc br 63$ 64$: tst (r1)+ sob r5, 62$ MFHLT #MAPLEN ; sub #4*2, r0 ; asr r0 ; mov r0, r5 ;low mem 65$: mfhlt r1 com r0 66$: rol r0 beq 67$ adc high clc br 66$ 67$: tst (r1)+ sob r5, 65$ asl low asl low asl high asl high mov #s.time-1,r4 movb #'k, -(r4) mov high, r3 mov #3, r5 call dec0 movb #40, -(r4) movb #40, -(r4) movb #'k, -(r4) mov low, r3 mov #3, r5 call dec0 movb #40, -(r4) movb #40, -(r4) movb #'k, -(r4) mov low, r3 add high, r3 mov #3, r5 call dec0 br 80$ 70$: mov #s.nomem,r0 mov #s.mem, r1 72$: tstb (r0) beq 80$ movb (r0)+, (r1)+ br 72$ ;------------------------------------------------------------ 80$: return .enabl lsb oct: mov #8., exp br 10$ dec: mov #10., exp 10$: clr r2 div (pc)+, r2 exp: .blkw 1 bis #'0, r3 movb r3, -(r4) mov r2, r3 sob r5, 10$ return .dsabl lsb .enabl lsb oct0: mov #8., exp0 br 10$ dec0: mov #10., exp0 10$: clr r2 div (pc)+, r2 exp0: .blkw 1 bis #'0, r3 movb r3, -(r4) mov r2, r3 beq 20$ sob r5, 10$ 15$: return 20$: dec r5 beq 15$ movb #40, -(r4) br 20$ .dsabl lsb runn: .word 0 num: .word 0 low: .word 0 high: .word 0 next: .word pdptr st.run: .ascii /Run / st.wai: .ascii /Wait/ st.io: .ascii "I/O " st.int: .ascii /Int / st.tim: .ascii /Tim / str0: .ascii <33>/[2J/<33>/[H/ .asciz /Num Name Descriptor Priority State Mem: Low High CPU Time/ .asciz /Num Name Desc.addr Priority State Mem Low High CPU Time/ str1: .asciz /--- ---------------- ------ ------ ---- ---- ---- ---- --------/ s.num: .ascii / 1 / s.name: .ascii /Operating system / s.da: .ascii /102062 / s.pri: .ascii /-00001 / s.stat: .ascii /Run / s.mem: .ascii /768k 12k 160k / s.time: .asciz / 2.58.03 / s.nomem:.asciz / No memory map / .even .end start[свернуть]
- - - Добавлено - - -
Вроде бы при обработке прерывания HALT всегда сначала смотрится HR1, потом HR0:
Скрытый текст
Код:;--------------------------------5$: ; mov ppib, r0 ; bis #340, r0 ; mtps r0 ; bvc write ; bcc read ; beq ioint ; br hlt ; ;------------------------------------------------ read: ; mov hr1, r1 ; beq 100$ ; mov -20000(r1),r0 ; l.rda beq trap4. ; bpl 100$ ; add #4, r0 ; movb #rd, (r0) ; call $$put1 ; ;................................ 100$: mov hr0, r1 ; mov -20000(r1),r0 ; l.rda beq trap4. ; bpl h.int ; add #4, r0 ; movb #rd, (r0) ; br $$put0 ; ;---------------------------------------- write: mov hr1, r1 ; beq 10$ ; bic #30000, r1 ; l.reg mov 10000(r1),r0 ; l.rda bpl jrq ; bic (r0)+, (r1) ; l.reg bis (r0)+, (r1) ; movb #wr+rd, (r0) ; call $$put1 ; ;................................ 10$: mov hr0, r1 ; bic #30000, r1 ; l.reg mov 10000(r1),r0 ; l.rda bpl jrq ; bic (r0)+, (r1) ; bis (r0)+, (r1) ; movb #wr+rd, (r0) ;[свернуть]
А так интересно, если не установлен EF1, то запись, если не установлен EF0, то чтение. Хотя логика может быть и инверсной.
nzeemin(03.01.2023)
Alex_K(04.01.2023)
По ПЛМ получается, что EF0 устанавливается при любом обращении к регистру эмуляции, а EF1 только при операции записи. Там ещё довольно приличная схема удержания этих сигналов, очень много условий.
- - - Добавлено - - -
nzeemin, а чтобы решить этот вопрос, то надо посмотреть таблицу эмулируемых регистров в памяти, а также на реальной машине запустить IOSCAN. Да, я тоже видел в EmuStudio много разных регистров в конце памяти. Кстати IOSCAN лучше запустить на голой системе, чтобы лишние процессы не подгрузились, прервать исполнение STARTS.COM при загрузке двойным нажатием УПР+C.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)