; Резидентная часть драйвера винчестера ; с загрузчиком ; ================================= ; *** Written by Oleg H. aug 1996 *** .TITLE HDD-disk resident .LIST TTM .DSABL GBL .ENABL LC ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect Code .Psect Proc .Psect PPsbio .Psect PP.Ins .Psect Data .Psect Text,d .Psect PP.Res ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .macro mput adrmp jsr r2,mput$ .word adrmp .endm .macro .Exit clr pc .endm .macro .Print msg .if nb, jsr r5,Prnt$1 .word msg .iff jsr r5,Prnt$2 .endc .endm .macro .Eprint msg jsr r5,E$print .word msg .endm ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ WD$csr = 176670 WD$vec = 144 pw$vec = 24 rsk2 = 176674 rdk2 = 176676 keyprc = 111144 dprc0 = 174152 disp = 174164 rap = 177010 rdp = 177014 WD$reg = 177054 sysreg = 177716 casadr = 32 ; 26 ; with 600 ! PASWRD = 342 ADRPRC = 7126 ; Процесс рестарта PPBase = 1100 NPart = 8. WD$cqe = <1022-1010>/2 DefBot = 120 DefTim = 122 ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect code start: ;------ .iif df,casset mov #Casset,R0 ; Кассета 0 для отладки mtps (pc) Reset ash #3,r0 ; Бит выбора кассеты bis r0,N.Cas ; Nо кассеты для инсталлятора bis r0,NN.Cas ; Nо кассеты для RW-процедуры .Print Ver Call sb$r ; Читаем мастер-блок 3$: Call sb.tst ; mov sbbuf,r1 beq 5$ .Print SbCRC 5$: ; Настройка резидента movb (r1)+,Spt ; Секторов на дорожку movb (r1)+,r3 ; Головок в цилиндре mul Spt,r3 mov r3,SptHed ; Секторов в цилиндре mov #DevTab,r0 ; Заполняем таблицу партиций clr r2 inc r2 clr r3 10$: mov r3,(r0)+ mov r2,(r0)+ tst (r1) beq 20$ Cmpb Max.PN,#'7 ; Не более 8 Bhis 20$ ; Boot-разделов incb Max.PN 20$: add (r1)+,r2 adc r3 cmp r0,#E$Dtab blo 10$ Mput Lo$Ins ; Забросим инсталлятор Mput Ex$Ins ; И выполним его mov #alread,r0 WaiTes = :.+2 1$: mov #-1,r5 ; Ждем кода возврата инсталлятора bmi 1$ ; *** RETCOD: 0 - already load; 1 - No memory; 2 - Load OK **** beq loadOK mov #Succes,r0 dec r5 bne LoadOK .EPrint NoMem ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ LoadOK: .print mov #100,r2 mov (r2),-(sp) mov #Tim$lc,(r2) bic #^c7,SbBuf+DefBot bisb SbBuf+DefBot,Cur.PN cmpb Max.PN,#'1 blt Sb.Nwr ; Единственная парт. - не спрашивать bgt Qpart movb #',,Max.PN-1 Qpart: .print Q.Part 15$: mov SbBuf+DefTim,Tim$w 16$: tst Tim$w bmi Sb.Exi 17$: tstb @#177560 bpl 16$ movb @#177562,r0 cmpb r0,#177 ; переписать суперблок безусловно beq Sb.Wr cmpb r0,#15 ; Не дожидаясь тайм-аута - default beq Sb.Exi cmpb r0,#40 bne 300$ clr r4 mov SbBuf+DefTim,r5 add #25.,r5 div #50.,r4 cmp r4,#9. ble 170$ mov #9.,r4 170$: add #'0,r4 movb r4,Cur.T .Print Q.Wait 171$: tstb @#177560 bpl 171$ movb @#177562,r3 cmpb r3,#15 beq 173$ cmpb r3,#'0 blt 171$ cmpb r3,#'9 bgt 171$ movb r3,Cur.T sub #'0,r3 mul #50.,r3 cmp r3,SbBuf+DefTim beq 173$ mov r3,SbBuf+DefTim clr r1 173$: .Print Cur.T br Qpart 300$: cmpb r0,#'0 blo 15$ cmpb r0,Max.PN bhi 15$ cmpb r0,Cur.PN ; Если тот же раздел - не писать beq 400$ movb r0,Cur.PN movb r0,SbBuf+DefBot clr r1 400$: Sb.Exi: tst r1 ; bne Sb.NWr ; Sb.Wr: call Sb.clc ; mov sbbuf,r1 Call sb$w ; write superblock Sb.NWr: mov (sp)+,(r2) ; @#100 .Print Cur.PN .print CrLfLf movb Cur.PN,r0 bicb #^c7,r0 ; Номер привода movb r0,SbRead+3 mov #WD$vec,r3 mov #Sb$Lc,(r3)+ ; Читаем 0-блок mov #paswrd,(r3) 31$: tstb (r3) bmi 31$ bne B0$Err asl r2 ; 100 -> 200 mtps r2 ; #200 clr r3 mov #SbBuf,r1 ; Копируем начальный загрузчик в 0 40$: mov (r1)+,(r3)+ mov (r1)+,(r3)+ sob r2,40$ mtps r2 clr pc ; Пуск начального загрузчика B0$Err: .EPrint B0.Err ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect data Lo$Ins: .byte 0,20,32,0 ; Запись инсталлятора .word PPBase .Word InsBeg,/2 Lo$SB: .byte 0,20,32,0 ; Запись RW0-процедур .word PPBase .Word Sb.RW,/2 Ex$Ins: .byte 0,30,32,0 ; Запуск инсталлятора .word PPBase Ex$SbR: .byte 0,30,32,0 ; Чтение суперблока .word PPBase+Sb.R-Sb.RW Ex$SbW: .byte 0,30,32,0 ; Запись суперблока .word PPBase+Sb.W-Sb.RW SbRead: .word 0 ; Q$blkn .word 0 ; Q$func ! Q$unit .word SbBuf ; Q$buff .word 400 ; Q$wcnt .Word SbRead ; ...CQE .blkw WD$Cqe-3 Tim$lc: dec (pc)+ Tim$w: .word 10. Sb$Lc: Rti ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect Text .REM % Alread: .asciz /?WDROM-I-Резидент уже был загружен/<15><12> Succes: .asciz /?WDROM-I-Резидент загружен успешно/<15><12> SbCRC: .asciz /?WDROM-W-Ошибка контрольной суммы/<15><12> B0.Err: .asciz /?WDROM-F-Ошибка чтения блока 0/<15><12> Sbioer: .asciz /?WDROM-F-Ошибка чтения мастер-блока/<15><12> NoMEM: .ascii /?WDROM-F-Нет памяти в ОЗУ ПП/<15><12> Ver: .Ascii /WDROM V01.01 by Oleg H./ CrLfLf: .byte 15,12,12,0 Q.Wait: .asciz <15>/Время ожидания, с (0-9): / Q.part: .ascii <12><15>/Номер boot-раздела (0-/ Max.PN: .byte '0-1 .ascii /): /<033><247><65><33><244> Cur.PN: .asciz /0/<10><033><277><244> % Alread: .asciz <204>/уже был /<211><212> Succes: .asciz <204><211>/ успешно/<212> SbCRC: .asciz <202>/W/<205>/контрольной суммы/<212> B0.Err: .asciz <207><210>/ 0/<212> Sbioer: .asciz <207>/мастер-/<210><212> NoMEM: .asciz <203>/-Нет памяти в ОЗУ ПП/<212> Ver: .Ascii <201>/ V01.01 by Oleg H./ CrLfLf: .byte 12,212,33,247,66,0 Q.Wait: .ascii <15>/Время ожидания, с (0-9): /<033><244> Cur.T: .asciz /0/<10><033><277><244> Q.part: .ascii <12><15>/Номер boot-раздела (0-/ Max.PN: .byte '0-1 .ascii /): /<033><247><65><033><244> Cur.PN: .asciz /0/<10><033><277><244> W$tab: .asciz /WDROM/ ; 201 ; WDROM .asciz /?/<201>/-/ ; 202 ; ?WDROM- .asciz <202>/F/ ; 203 ; ?WDROM-F .asciz <202>/I-Резидент / ; 204 ; ?WDROM-I-Резидент .asciz /-Ошибка / ; 205 ; .asciz <203><205> ; 206 ; ?WDROM-F-Ошибка .asciz <206>/чтения / ; 207 ; ?WDROM-F-Ошибка чтения .asciz /блока/ ; 210 ; .asciz /загружен/ ; 211 ; .byte 15,12,0,0 ; 212 ; .even ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect proc MPut$: call 5$ ; Подождем готовности К2 1$: call 4$ ; Вытолкнем в К2 первые 2 байта адрес clrb @-(r2) ; Очистим байт ответа jsr r2,3$ ; Передадим 2 байта завершения 377 .word -1 ; tstb @(r2)+ ; Проверим ответ 2$: rts r2 ; Выйдем в основную программу 3$: push #2$ ; 4$: push pc ; Обеспечим повторный вход movb (r2)+,@#rdk2 ; Передача байта в К2 5$: tstb @#rsk2 ; Ожидание готовности К2 bpl 5$ ; return ; выход ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ E$print: mov #5747,2(r5) ; tst -(pc) Prnt$1: mov (r5)+,r0 Prnt$2: br 7$ 5$: push r0 mov r4,r0 jsr r5,7$ pop r0 inc r0 7$: mov #W$tab,r4 mov #201,r3 8$: cmpb (r0),r3 beq 5$ 10$: tstb (r4)+ bne 10$ inc r3 tstb (r4) ; Конец массива слов ? bne 8$ ; Нет 20$: tstb @#177564 bpl 20$ movb (r0)+,@#177566 bne 7$ rts r5 ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ Sb.Tst: jsr r2,crcclc .word 377 add (r3),r5 bis r4,r5 Return Sb.clc: jsr r2,crcclc .word 376 inc r5 neg r4 neg r5 mov r4,(r3)+ mov r5,(r3) Return crcclc: mov (r2)+,r0 mov #SbBuf,r1 mov r1,r3 clr r4 clr r5 2$: add (r3)+,r4 adc r5 sob r0,2$ Rts r2 ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ SB$R: call $comon Mput Ex$SBR return SB$W: call $comon Mput Ex$SBW $ret..: return $comon: mput lo$sb mov #-1,sb$WF call @(sp)+ $$$com: tst (pc)+ sb$WF: .blkw 1 bmi $$$com beq $ret.. .EPrint SbIOer ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect pp.ins ; RETCOD: 0 - already load; 1 - No memory; 2 - Load OK InsBeg: clr r3 tst @#casadr bne 100$ inc r3 N.Cas = .+2 mov #6,@#CasAdr ; Установим No кассеты для резидента mov #Rap,r4 mov #R$end-R$beg,r0 mov r0,r2 Call @#176132 ; Getmem(); r0 - size, r1 - pointer cmp r0,r2 ; А дали достаточно памяти ? blo 100$ inc r3 mov #R$beg/2,(r4) ; Asr r0 jsr r5,@#125602 ; Copy resident... ; r1 указывает на буфер за конец резидента add r1,reldot-r$end(r1) ; Релокация mov @#adrprc,r0 ; Адрес bmi 10$ mov r0,jmpadr-r$end(r1) 10$: add #S$beg-R$end,r1 ; Адрес входа в резидент mov r1,@#adrprc 100$: mov #WaiTes/2,(r4) mov r3,@#rdp Return InsEnd: ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect PPsbio sb.rw: Sb.W: jsr r3,sbcomm mov @(pc)+,(r3) .word 177717 Sb.R: jsr r3,sbcomm mov (r3),@(pc)+ .word 177737 Sbcomm: tst (sp)+ call int.d 2$: call int... tstb @#110000 bpl 2$ ; Device BUSY mov #110014,r4 10$: mov Sb.Tab-Sb.rw+PPbase-110014-2(r4),-(r4) bmi 10$ mov (r3)+,Sb.Cmd ; Команда пиши/читай mov (r3)+,-(r4) ; КОП в винчестер Mov #400,R0 ; 400 - размер блока 20$: call int... movb (r4),r1 bpl 20$ ; BSY asr r1 bcc sbIerr bic #^c44,r1 bne 20$ mov #110016,r3 mov #SbBuf/2,@#Rap sb.cmd: .blkw 1 .word Rdp inc @#Rap sob r0,sb.cmd sbIerr: ;/////////// mov #sb$WF/2,@#rap mov r0,@#Rdp ; 0 - if OK; 400 - if error int.e: mov R5,@#WD$reg mtps #0 return Int...: call int.e int.d: mov @#WD$reg,R5 ; Сохраним старое состояние mtps (pc) NN.Cas = .+2 mov #6,@#WD$reg ; И подключим СПЗУ return ; 110002 110004 110006 110010 110012 ; s:d:h trk-hi trk-lo sct Nsct .word <^c100> & 377, ^c0, ^c0, ^c1, ^c1 Sb.Tab: .Even sb.rw.e: ;╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣╣ .Psect pp.res R$beg: .rad50 /WD SYS/ S$beg: mtps (pc) ; Загрузим PSW == 304 mov #rap,r4 mov r1,-(sp) mov @#WD$reg,-(sp) ; Сохраним старое состояние mov @#CASADR,@#WD$reg ; И подключим СПЗУ tstb @#110000 bpl PL.nop ; Device BUSY mov #rdp,r5 mov (pc)+,r2 wcnt: .word 0 bgt common ; Еще чего-то надо доделать mov #+1,(r4) ; Указывает на PSW в векторе ЦМ cmp #paswrd,(r5) bne NE.nop ; Пустой вызов - выйти 1$: clr RetCod ; Код возврата установим в 0 ;;;; movb @#110014,RetCod+1 ;******************* DBG ********** ; ** Извлечение из ЦП параметров dec (r4) ; Указатель на WDint mov (r5),(r4) ror (r4) sub #WD$cqe,(r4) ; Указатель на WDcqe mov (r5),(r4) ror (r4) ; Указатель на элемент очереди mov (r5),r3 ; Номер блока inc (r4) mov (r5),r1 ; Номер устройства в ст. байте 10$: clrb r1 ash #-6,r1 ; -8 + 2 - смещ. в таблице add (pc)+,r1 ; Указ. на DevTab (ст. слово) reldot: .word DevTab-R$End mov (r1)+,r2 mov 4(r1),r0 sub (r1),r0 ; Размер раздела (партиции) beq E.bad ; Если == 0, - ошибка ! cmpb (r5),#373 ; Spfun "SIZE" ? bne 20$ ; Обработка SpFun_373 inc (r4) ; Теперь указывает на @буфер mov (r5),(r4) ror (r4) ; Теперь указывает на буфер mov r0,(r5) br exit00 20$: tstb (r5) bne E.bad inc (r4) ; Теперь указывает на @буфер sub r3,r0 ; Сколько блоков еще можно читать ; из этого раздела blo E.bad ; Нельзя за границу раздела !!! add (r1),r3 ; R2,R3 - 32-х разрядный абсолютный adc r2 ; номер блока на винчестере SPTHED = :.+2 div #1,r2 mov #110006,r1 com r2 mov r2,(r1) ; Дорожка мл swab r2 mov r2,-(r1) ; Дорожка ст clr r2 SPT = :.+2 div #1,r2 bis #100,r2 ; Размер сектора-512 com r2 com r3 sbc r3 mov r2,-(r1) ; Поверхность mov r3,@#110010 ; Сектор mov (r5),buff ; Buffer ror buff jsr r5,Set$RW ; ёУстановим режим чтения mov (r3),(r5) ; ╥ tst (r3) ; ╥ .word 177737 ; ╧ inc (r4) mov (r5),r2 ; Количество слов beq exit0 bpl 1$ neg r2 jsr r5,Set$RW ; ёУстановим режим записи mov (r5),(r3) ; ╥ clr (r3) ; ╥ .word 177717 ; ╧ 1$: mov r2,r3 add #377,r3 clrb r3 swab r3 ; Сколько блоков читать (мл. байт) cmp r3,r0 blos 10$ mov r0,r3 10$: com r3 mov r3,@#110012 ; Кол-во секторов mov r1,@#110000 ; Старт операции mov r2,wcnt Common: mov (pc)+,(r4) buff: .blkw 1 mov #110016,r3 next$b: movb @#110000,r1 PL.nop: bpl ex.nop ; BSY asr r1 bcs 10$ movb @#110014,RetCod+1 E.bad = . ; I/O ERROR inc RetCod Exit00 = . clr r2 br exit0 10$: bic #^c44,r1 NE.nop: bne ex.nop Mov #400,R0 ; 400 - размер блока sub r0,r2 bge copy add r2,r0 copy: Add #3,r0 ashc #-2,r0 ashc #-14,r1 sub #14,r1 sub r1,pc cmd1: .blkw 1 inc (r4) cmd2: .blkw 1 inc (r4) cmd3: .blkw 1 inc (r4) cmd4: .blkw 1 inc (r4) sob r0,cmd1 mov (r4),buff mov r2,wcnt bgt common ; R2 < 0 -Флаг - надо доделать операцию exit0: mov #+1,(r4) RetCod = :.+2 mov #0,(r5) ; Код ошибки dec (r4) mov (r5),r0 ; Вектор прерывания mov #pw$vec/2,(r4) mov (r5),r1 mov r0,(r5) ; Указатель на WD$int bic #100000,@#sysreg ; Прерывание в ЦМ bis #100000,@#sysreg ; Прерывание в ЦМ clr wcnt ; Оп. завершена mov r1,(r5) ; Восстановим 24 вектор neg r2 ble rest24 cmd5: .blkw 1 sob r2,cmd5 rest24: ex.nop: mov (sp)+,@#WD$reg mov (sp)+,r1 mov r1,@#adrprc ; Занесем адрес первого процесса mtps (pc) ; Загрузим PSW == 117 jmp @(pc)+ jmpadr: .word disp ; Вернемся в диспетчер Set$RW: mov (r5),Cmd1 mov (r5),Cmd2 mov (r5),Cmd3 mov (r5)+,Cmd4 mov (r5)+,Cmd5 mov (r5)+,r1 Rts r5 DevTab: ; .Blkw 2*9. ;E$Dtab: ;R$end: E$Dtab = DevTab + <2*2*<1+8.+8.+8.+1>> R$end = E$Dtab SbBuf = E$Dtab .END start