Заголовочный модуль для каналов
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

 

PROGRAM $M0

B16

1000 VALUE TOTMEMLEN

TOTMEMLEN BYTE VCTR MEMORY

: T-1 D -1 ;

: *4 SHL SHL ;

: &0FF 0FF & ;

: <= 1+ < ;

: >= 1- > ;

[20 WORD VCTR CHAN] [каналы. Начиная с 5-го]

VAR NCHAN [Номер текущего канала]

: !NCHAN ! NCHAN ;

 

5 VALUE NBASECH [Первый не базовый канал]

 

: GETDATA NCHAN 10 * + CHDATA ;

: PUTDATA NCHAN 10 * + ! CHDATA ;

 

[Размер заголовка блока в байтах]

FIX VAR HSIZE 10 ! HSIZE

: HSIZE+ HSIZE + ;

 

[Pred, Next, BusyLen, Len]

1 *4 VALUE ctfPREDADDR

 

[$M4] [как самодостаточный]

0 VALUE ctLOWCH [Нижний канал.]

             [0=Оперативная/1=Дисковая память/2=Журнал/-1=свободен]

1 VALUE ctTEKADR [Логический адрес внутри участка (по данным)]

2 VALUE ctBUSYLEN [Длина фрагмента, занятая данными]

3 VALUE ctLEN [Максимальная допустимая длина данных фрагмента]

4 VALUE ctTEKADR0 [=TEKADR, когда TEKADR стоит на нулевом байте данных фрагм]

 

5 VALUE ctNEXTADDR [Адрес начала заголовка следующего фрагмента (пф)]

6 VALUE ctPREDADDR [Адрес начала заголовка предыдущего фрагмента (пф)]

7 VALUE ctSYNCADDR [Адрес начала заголовка фрагмента (пф)]

8 VALUE ctCHGCTX [признак изменения контекста]

9 VALUE ct1STLONG [Первое число в канале]

[в начальном блоке в начальном слове данных лежит адрес начала данных]

 

: LOWCH ctLOWCH GETDATA ; : !LOWCH ctLOWCH PUTDATA ;

: TEKADR ctTEKADR GETDATA ; : !TEKADR ctTEKADR PUTDATA ;

: TEKADR0 ctTEKADR0 GETDATA ; : !TEKADR0 ctTEKADR0 PUTDATA ;

: TEKADR++ TEKADR 1+ !TEKADR ; : !+TEKADR TEKADR + !TEKADR ;

: BUSYLEN ctBUSYLEN GETDATA ; : !BUSYLEN ctBUSYLEN PUTDATA ;

: LEN ctLEN GETDATA ; : !LEN ctLEN PUTDATA ;

: NEXTADDR ctNEXTADDR GETDATA ; : !NEXTADDR ctNEXTADDR PUTDATA ;

: PREDADDR ctPREDADDR GETDATA ; : !PREDADDR ctPREDADDR PUTDATA ;

: SYNCADDR ctSYNCADDR GETDATA ; : !SYNCADDR ctSYNCADDR PUTDATA ;

: CHGCTX ctCHGCTX GETDATA ; : !CHGCTX ctCHGCTX PUTDATA ;

: FSTLONG ct1STLONG GETDATA ; : !FSTLONG ct1STLONG PUTDATA ;

 

TRAP NOMEMORY NOMEMORY#

: NOMEMORY# ."

No free memory" ;

 

TRAP OUTDATA OUTDATA#

: OUTDATA# ."

Out of data. " ;

 

TRAP OUTMEM OUTMEM#

: OUTMEM# ."

Out of memory. " ;

 

TRAP UNKCH UNKCH#

: UNKCH# ."

Unknown primitive channel:" NCHAN .D CR ;

 

TRAP O_NOTFND NOTFND#

 

: NOTFND# ."

Object not found. OID=" . CR ;

 

[*** Информация по каналу ***]

: IC CR

 ." NCHAN=" NCHAN .D SP ." LOWCH=" LOWCH .D CR

 ."SYNCADDR=" SYNCADDR .D SP ."PREDADDR=" PREDADDR .D SP ."NEXTADDR="

NEXTADDR .D CR

 ." BUSYLEN=" BUSYLEN .D SP ." LEN=" LEN .D CR

 ." TEKADR0=" TEKADR0 .D SP ." TEKADR=" TEKADR .D CR ;

 

CHANNEL DATACH "DATA." CONNECT DATACH

 

 

Менеджер виртуальной памяти

 

 

PROGRAM $M2

B16          [физическая организация памяти]

 

[вычисление физического адреса и номера базового канала]

:: : POSIX [addr(i)] NCHAN C NBASECH < BR+ LEAVE [addr nchan] D

             GOTO DELTA2 S( NCHAN ) TOLOW POSIX [addr(i-1)] ;

 

:: : TOLOW LOWCH !NCHAN ;

 

[Пересчет адреса в адрес нижнего уровня: TEKADR(i) -> TEKADR(i-1)]

:: : DELTA2 SYNCADDR HSIZE + TEKADR TEKADR0 - + ;

 

:: : IBS EON OUTDATA OUTDATA# LAST?

       TEKADR POSIX TEKADR++ S( NCHAN ) !NCHAN BSGOTO

NCHAN BR 0 IBS0 1 IBS1 [2 IBS2] ELSE UNKCH ;

:: : OBS EON OUTDATA OUTDATA# LAST?

    TEKADR POSIX TEKADR++ S( NCHAN ) !NCHAN BSGOTO

    NCHAN BR 0 OBS0 1 OBS1 [2 OBS2] ELSE UNKCH ;

: LAST? TEKADR BUSYLEN TEKADR0 + = IF0 LEAVE NEXTBLK ;

 

 

[переход для базового канала ]

: BSGOTO [ADDR] NCHAN BR 0 BSGOTO0 1 BSGOTO1 [2 BSGOTO2] ELSE UNKCH ;

: BSGOTO0 !TEKADR ;

: BSGOTO1 C !TEKADR HSIZE+ SPOS DATACH ;

[ : BSGOTO2 C !TEKADR HSIZE+ SPOS JOURCH ;]

 

0 %IF

: ADDR [PARAGRAF OFFSET] + [address] ; [Сейчас пгф=1 байту]

 [Для файлов можно сделать неск. файлов и распределить по ним пространство]

%FI

 

: IBS0 TEKADR HSIZE+ MEMORY &0FF TEKADR++ ;

: IBS1   IB DATACH &0FF TEKADR++ ;

[: IBS2     IB JOURCH &0FF TEKADR++ ;]

 

: OBS0 &0FF TEKADR HSIZE+ ! MEMORY TEKADR++ ;

: OBS1 &0FF   OB DATACH TEKADR++ ; [Запись байта]

[: OBS2 &0FF   OB JOURCH TEKADR++ ;] [Запись байта]

 

:: : GOTO NCHAN NBASECH < BR+ BSGOTO VGOTO ;

: VGOTO TEKADR - @GOTO ;

 

[Переход по смещению]

:: : @GOTO C BRS @GOTO- D @GOTO+ ;

: @GOTO+ DO @GOTO1+ ;

: @GOTO- NEG DO @GOTO1- ;

: @GOTO1+

       EON OUTDATA OUTDATA#

       TEKADR TEKADR0 BUSYLEN + =

       IF+ NEXTBLK TEKADR 1+ !TEKADR ;

: @GOTO1-

       EON OUTDATA OUTDATA#

       TEKADR TEKADR0 =

       IF+ PREDBLK TEKADR 1- !TEKADR ;

 

: NEXTBLK CHGCTX IF+ SCTX NEXTADDR NOEXIST? !SYNCADDR RELCTX

       TEKADR !TEKADR0 ;

: NOEXIST? [ADDR] C -1 = IF+ OUTDATA [ADDR] ;

 

[Pred, Next, BusyLen, Len]

:: : LCTX' [UPCH] PUSH TEKADR ILS ILS ILS ILS POP

  NCHAN E2 !NCHAN !LOWCH !LEN !BUSYLEN !NEXTADDR !PREDADDR !SYNCADDR

  0 !CHGCTX ;

[Грузить параметры канала]

:: : LCTX [newch] LCTX' 0 !TEKADR 0 !TEKADR0 ;

: RELCTX TEKADR0 TEKADR NCHAN SYNCADDR TOLOW GOTO LCTX !TEKADR !TEKADR0 ;

: PREDBLK CHGCTX IF+ SCTX PREDADDR NOEXIST? !SYNCADDR RELCTX

       TEKADR BUSYLEN - !TEKADR0 ;

 

: IBSC [CHAN] S( NCHAN ) !NCHAN IBS ;

: ILSC S( NCHAN ) !NCHAN ILS ;

: OBSC [N CHAN] S( NCHAN ) !NCHAN OBS ;

: IOBSCC [SRC DST] C2 IBSC C2 OBSC ;

 

: DO_IOBSCC [SRC_CH DST_CH N] S( NCHAN )

C3 !NCHAN 0 GOTO DO IOBSCC [SRC DST] ;

 

: IWS IBS IBS SWB &0 ;

: ILS IWS IWS SETHI ; [SWW &0]

: OWS C OBS SWB OBS ;

: OLS C OWS SWW OWS ;

 

[Перейти к конечному блоку]

: GOTOENDBK NEXTADDR -1 = EX+ BUSYLEN TEKADR0 +

       NEXTADDR !SYNCADDR RELCTX C !TEKADR0 !TEKADR ;

: GOBOTTOM RP GOTOENDBK BUSYLEN TEKADR0 + GOTO ;

: LENVMEM GOBOTTOM TEKADR [LEN] ; [длина виртуальной памяти]

: LASTADDR SYNCADDR LEN + HSIZE+ ;

: OBS-0 NCHAN BR 0 OBS00 1 OBS01 [2 OBS02] ELSE OBS0N ;

: OBS00 0 OBS0 ; : OBS01 0 OBS1 ; [: OBS02 0 OBS2 ;] : OBS0N 0 OBS ;

 

[Спецификация: Размер увеличивается на N байт. Если это невозможно,

          возникает исключительная ситуация NOMEMORY.

После работы мы стоим в том же канале в начале выделенного пространства. ]

: UPSIZE [N] GOBOTTOM TEKADR E2 UPSIZE' GOTO [] ;

: UPSIZE' [N] GOBOTTOM LEN BUSYLEN - CALCOST [HARD SOFT] UPSIZEI

     C BR0 D UPSIZEO ;

: CALCOST [N FREE] C2C2 <= BR+ COST1 COST2 [HARD SOFT] ;

: COST1 [N FREE] T0 E2 [0 N] ;

: COST2 [N FREE] C PUSH - POP [N-FREE FREE] ;

 

 : UPSIZEI [N_SOFT] BUSYLEN + !BUSYLEN 1 !CHGCTX SCTX ;

 : UPSIZEO [N_HARD] NCHAN BR 0 USO0 1 USO1 2 USO1 ELSE USON ;

 : USO1 C GOBOTTOM TEKADR E2 DO OBS-0 [!TEKADR] BSGOTO

   C BUSYLEN + !BUSYLEN LEN + !LEN 1 !CHGCTX SCTX ;

 : USO0 NOMEMORY [Сюда можно вставить упаковку] ;

 

[Спецификация: увеличение размера (жестко, т.е. за счет нижнего уровня)]

 

 : USON [N] SYNCADDR LASTADDR USON1 RELCTX [>] UPSIZE' ;

 : USON1 S( NCHAN ) TOLOW BUSYLEN = BR+ USON_ADD USON_NEW ;

[Расширение увеличением длины фрагмента]

: USON_ADD C2 [N SYNCADDR N] UPSIZE' C BUSYLEN E2 - HSIZE - E2

         [N LEN SYNCADDR] 3 *4 + GOTO OLS [N] [UPSIZEI] ;

[Расширение созданием нового фрагмента]

: USON_NEW C2 [N SYNCADDR N] [GOBOTTOM] C HSIZE+ UPSIZE'

[N SYNCADDR N] C2 -1 0 C4 TEKADR PUSH WRITECTX D 4+ GOTO POP OLS [N] ;

: WRITECTX [PRED NEXT BUSY LEN] C4 OLS C3 OLS C2 OLS C OLS DD DD ;

 

FIX VAR UPCONST 10 ! UPCONST [Этому числу байт кратно увеличение]

[Увеличение размера нижнего уровня]

[увеличение физического размера этого уровня]

 

: SCTX CHGCTX IF0 LEAVE 0 !CHGCTX NCHAN BR 0 NOP 1 SCTX1 [2 SCTX2]

3 NOP 4 NOP ELSE SCTXN ;

: SCTXN TEKADR NCHAN LEN BUSYLEN NEXTADDR

  PREDADDR SYNCADDR TOLOW GOTO 4 DO OLS !NCHAN GOTO ;

: SAVEALL NOP ; [СОХРАНИТЬ ВЕСЬ КАНАЛ НА ПЕРВИЧНОМ УСТРОЙСТВЕ (ИСТОЧНИКЕ)]

: SCTX1 POS DATACH 8 SPOS DATACH BUSYLEN OL DATACH LEN OL DATACH SPOS DATACH ;

[

: SCTX2 POS JOURCH 8 SPOS JOURCH BUSYLEN OL JOURCH LEN OL JOURCH SPOS JOURCH ;

]

[Новая виртуальная память]

0 %IF

: NEWVM [N] TEKADR C2 HSIZE+ UPSIZE GOTO -1 -1 C3 C WRITECTX D ;

%FI

 

: NEWVM [N] C HSIZE+ UPSIZE TEKADR PUSH -1 -1 0 C4 WRITECTX DO OBS-0

POP [SYNCADR] ;

: END? NEXTADDR -1 = TEKADR BUSYLEN TEKADR0 + = & ;

 

: NEWVM1 [N] C HSIZE+ UPSIZE TEKADR PUSH -1 -1 E3 C WRITECTX WRI_DATA

POP [SYNCADR] ;

 

: LOADCH0 0 !NCHAN 0 !LOWCH 0 !TEKADR 0 !BUSYLEN

     TOTMEMLEN !LEN 0 !TEKADR0 0 !SYNCADDR -1 !NEXTADDR -1 !PREDADDR ;

[ДЛЯ БАЗОВЫХ КАНАЛОВ LOWCH=NCHAN]

 

Дата: 2019-05-28, просмотров: 199.