Subversion Repositories pentevo

Rev

Rev 1026 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1.  
  2. ; LAST UPDATE: 09.10.2022 savelij
  3.  
  4.                 TITLE "virtual.a80"
  5.  
  6.                 DB 0xFF                         ; DCU
  7.  
  8. ; копирование 256 байт
  9. COPY_BLOCK
  10.         REPT 128                                ; копирование блока 256 байт
  11.                 LDI
  12.         ENDM
  13. COPYHBLOCK
  14.         REPT 126
  15.                 LDI
  16.         ENDM
  17.                 JR COPY_BLOCK1
  18.                
  19.                 DW 0xFFFF                       ; для вектора прерываний IM 2 I=9
  20.  
  21. COPY_BLOCK1     LDI
  22.                 LDI
  23.                 RET
  24.  
  25. ; номера внутренних функций
  26.  INIT_VAR
  27.  SETVAR _OUT_1F
  28.  SETVAR _OUT_3F
  29.  SETVAR _OUT_5F
  30.  SETVAR _OUT_7F
  31.  SETVAR _OUT_FF
  32.  SETVAR _OUTI
  33.  SETVAR _IN_1F
  34.  SETVAR _IN_3F
  35.  SETVAR _IN_5F
  36.  SETVAR _IN_7F
  37.  SETVAR _IN_FF
  38.  SETVAR _INI
  39.  SETVAR _OUT_C_D
  40.  SETVAR _IN_H_C
  41.  SETVAR _WR_RD_SECT
  42.  SETVAR _CMP_RAMDISK
  43. ; SETVAR _SET_VIRT_BITS
  44.  
  45.  SETVAR WOUTCA
  46.  SETVAR WWRITE_SEC_
  47.  SETVAR WREAD_SEC_
  48.  SETVAR WINI_RET
  49.  
  50. ; адреса внутренних функций
  51. ; с возвратом в место вызова
  52. W_DATA          DW W_OUT1F                      ; запись порта 1F
  53.                 DW W_OUT3F                      ; запись порта 3F
  54.                 DW W_OUT5F                      ; запись порта 5F
  55.                 DW W_OUT7F                      ; запись порта 7F
  56.                 DW W_OUTFF                      ; запись порта FF
  57.                 DW W_OUTI                       ; OUTI
  58.                 DW W_IN1F                       ; чтение порта 1F
  59.                 DW W_IN3F                       ; чтение порта 3F
  60.                 DW W_IN5F                       ; чтение порта 5F
  61.                 DW W_IN7F                       ; чтение порта 7F
  62.                 DW W_INFF                       ; чтение порта FF
  63.                 DW W_INI                        ; INI
  64.                 DW W_OUTCD                      ; запись регистра 'D' в порт 'BC'
  65.                 DW W_INHC                       ; чтение в регистр 'H' из порта 'BC'
  66.                 DW READ_WRITE_SEC               ; чтение/запись сектора
  67.                 DW CMP_RAM_DISK                 ; проверка RAM диска
  68. ;               DW SET_VIRT_BITS                ; установка переменной считанной из RST 8
  69. EW_DATA
  70. ; без возврата в место вызова
  71.                 DW W_OUTCA                      ; запись регистра 'A' в порт 'BC'
  72.                 DW WRITE_SEC_                   ; запись сектора без возврата в адрес вызова
  73.                 DW READ_SEC_                    ; чтение сектора без возврата в адрес вызова
  74.                 DW W_INI                        ; INI без возврата в адрес вызова
  75.  
  76. TEXT4VIRTDRV    DB 0x16,ZASTV_Y+2,1
  77. TXT4VIRTDRV     DC "Virtual Drive: "
  78. ETXT4VIRTDRV
  79.  
  80. DOS_NOEMUL      DB ROM_BAS48 | 0x80             ; страница DOS с эмуляцией только для 3D13
  81. DOS_EMUL        DB ROM_ADD_BAS48 | 0x80         ; страница DOS с полным перехватом портов
  82.  
  83. NUM_ALT_PAGE
  84.         IF EMU3D2F=1
  85.                 DB ROM_ADD_BAS48 | 0x80
  86.         ELSE
  87.                 DB ROM_BAS48 | 0x80
  88.         ENDIF
  89.  
  90. ; обработчик RST 30
  91. RST30_WORK      EX (SP),HL
  92.                 PUSH AF
  93.                 PUSH BC
  94.                 LD A,I
  95.                 JP PE,RST30_WORK1
  96.                 LD A,I
  97. RST30_WORK1     DI
  98.                 PUSH AF
  99.                 LD A,(NUM_ALT_PAGE)             ; номер текущей страницы ПЗУ
  100.                 PUSH AF
  101.                 AND 0x3E                        ; номер реальной страницы без зависимости
  102.                 LD BC,WIN_A0
  103.                 OUT (C),A
  104.                 LD B,HIGH (WIN_P0)
  105.                 LD A,RAM_EVODOS
  106.                 OUT (C),A
  107.                 IN A,(PEVO_CONF)
  108.                 LD (WR_BF),A
  109.                 OR 1
  110.                 OUT (PEVO_CONF),A
  111.                 POP AF
  112.                 LD (TEK_ROMPAGE),A
  113.                 LD A,(HL)
  114.                 LD (DOS_STEK),SP
  115.                 LD SP,DOS_STEK
  116.                 PUSH HL                         ; положили HL = адрес возврата
  117.                 PUSH DE
  118.                 LD HL,(DOS_STEK)
  119.                 LD DE,REG_IF
  120.         REPT 8
  121.                 LDI
  122.         ENDM
  123.                 LD HL,EXIT_RST30
  124.                 PUSH HL                         ; положили адрес завершения
  125.                 LD HL,W_DATA
  126.                 ADD A,A
  127.                 ADD A,L        
  128.                 LD L,A
  129.                 LD A,(HL)
  130.                 INC L
  131.                 LD H,(HL)
  132.                 LD L,A
  133.                 JP (HL)
  134.  
  135. EXIT_RST30      LD HL,REG_IF
  136.                 LD DE,(DOS_STEK)
  137.         REPT 8
  138.                 LDI
  139.         ENDM
  140.                 POP DE
  141.                 POP HL
  142.                 LD SP,(DOS_STEK)
  143.                 LD A,(HL)
  144.                 INC HL
  145.                 CP LOW ((EW_DATA-W_DATA) / 2)
  146.                 JR C,EXIT_RST302
  147.                 LD HL,FOR_RET                   ; адрес выхода без возврата в место вызова
  148. EXIT_RST302     PUSH HL
  149.                 LD HL,(COPY_VIRT_BITS)
  150.                 LD A,(MASK_MNT_DRV)
  151.                 AND L
  152.                 LD A,ROM_ADD_BAS48 | 0x80       ; страница для 3D2F
  153.                 JR NZ,EXIT_RST305               ; выбор ROM 3D2F если есть примонтированный
  154.                 LD HL,(VIRT_DRIVE)              ; или проверка для рамдиска
  155.                 LD A,(MASK_WRK_DRV)
  156.                 CP L
  157.                 LD A,ROM_ADD_BAS48 | 0x80       ; страница для 3D2F
  158.                 JR Z,EXIT_RST305
  159.                 LD A,ROM_BAS48 | 0x80           ; страницы для 3D13
  160. EXIT_RST305     LD HL,(WR_BF)
  161.                 LD BC,WIN_A0
  162. EXIT_RST303     CALL WR_BYTE_RET
  163.                 LD A,L
  164.                 POP HL
  165.                 OUT (PEVO_CONF),A
  166.                 POP AF
  167.                 JP PO,EXIT_RST304
  168.                 EI
  169. EXIT_RST304     POP BC
  170.                 POP AF
  171.                 EX (SP),HL
  172.                 RET
  173.  
  174. ; запись "A" в порт 0x1F
  175. W_OUT1F         LD A,(REG_A)
  176.                 LD (WR_1F),A
  177.                 AND %11110000
  178.                 RRCA
  179.                 RRCA
  180.                 RRCA
  181.                 ADD A,LOW (.TABL_CMD)
  182.                 LD L,A
  183.                 ADC A,HIGH (.TABL_CMD)
  184.                 SUB L
  185.                 LD H,A
  186.                 LD A,(HL)
  187.                 INC HL
  188.                 LD H,(HL)
  189.                 LD L,A
  190.                 JP (HL)
  191.  
  192. .TABL_CMD       DW .CMD_00
  193.                 DW .CMD_10
  194.                 DW .CMD_20
  195.                 DW .CMD_30
  196.                 DW .CMD_40
  197.                 DW .CMD_50
  198.                 DW .CMD_60
  199.                 DW .CMD_70
  200.                 DW .CMD_80
  201.                 DW .CMD_90
  202.                 DW .CMD_A0
  203.                 DW .CMD_B0
  204.                 DW .CMD_C0
  205.                 DW .CMD_D0
  206.                 DW .CMD_E0
  207.                 DW .CMD_F0
  208.  
  209. ; 00-0F команда восстановления
  210. .CMD_00         XOR A
  211.                 LD (PORT_3F),A
  212.                 LD (PORT_5F),A
  213.                 OUT (0x3F),A
  214.                 OUT (0x5F),A
  215.                 JR .INFF_BIT6
  216.  
  217. ; 10-1F команда поиска
  218. .CMD_10         LD A,(PORT_7F)
  219.                 LD (PORT_3F),A 
  220.                 OUT (0x3F),A
  221.                 CALL DISK_NONE
  222.                 LD A,0x80
  223.                 JR C,.INFF_BIT61
  224. .INFF_BIT6      XOR A
  225. .INFF_BIT61     LD (RD_1F),A
  226.                 LD A,0xBF
  227.                 LD (RD_FF),A
  228.                 RET
  229.  
  230. ; 20-3F команда шаг в предыдущем направлении
  231. .CMD_20
  232. .CMD_30         LD A,(PORT_3F)
  233. .NAPRAVL        NOP
  234.                 LD (PORT_3F),A
  235.                 OUT (0x3F),A
  236.                 JR .INFF_BIT6
  237.  
  238. ; 40-5F команда шаг вперед
  239. .CMD_40
  240. .CMD_50         LD A,(PORT_3F)
  241.                 INC A
  242.                 LD (PORT_3F),A 
  243.                 OUT (0x3F),A
  244.                 LD A,0x3C                       ; INC A
  245.                 LD (.NAPRAVL),A
  246.                 JR .INFF_BIT6
  247.  
  248. ; 60-7F команда шаг назад
  249. .CMD_60
  250. .CMD_70         LD A,(PORT_3F)
  251.                 DEC A
  252.                 LD (PORT_3F),A 
  253.                 OUT (0x3F),A
  254.                 LD A,0x3D                       ; DEC A
  255.                 LD (.NAPRAVL),A
  256. ;               JR .INFF_BIT6
  257.  
  258. ; 80-9F команда чтение сектора
  259. .CMD_80
  260. .CMD_90
  261. ;               JR .INFF_BIT6
  262.  
  263. ; A0-BF команда запись сектора
  264. .CMD_A0
  265. .CMD_B0         JR .INFF_BIT6
  266.  
  267. .INFF_BIT7      XOR A
  268.                 LD (RD_1F),A
  269.                 LD A,0x7F
  270.                 LD (RD_FF),A
  271.                 RET
  272.  
  273. ; C0-CF чтение адреса
  274. .CMD_C0         JR .INFF_BIT6
  275.  
  276. ; D0-DF принудительное прерывание
  277. .CMD_D0         LD A,0xBF
  278.                 LD (RD_FF),A
  279.                 RET
  280.  
  281. ; E0-EF чтение дорожки
  282. .CMD_E0
  283. .CMD_F0         JR .INFF_BIT6
  284.  
  285. ; запись "A" в порт 0x3F
  286. W_OUT3F         LD A,(REG_A)
  287.                 LD (PORT_3F),A
  288.                 OUT (0x3F),A
  289.                 RET
  290.  
  291. ; запись "A" в порт 0x5F
  292. W_OUT5F         LD A,(REG_A)
  293.                 LD (PORT_5F),A
  294.                 OUT (0x5F),A
  295.                 RET
  296.  
  297. ; запись "A" в порт 0x7F
  298. W_OUT7F         LD A,(REG_A)
  299.                 LD (PORT_7F),A
  300.                 OUT (0x7F),A
  301.                 RET
  302.  
  303. ; запись "A" в порт 0xFF
  304. W_OUTFF         LD A,(REG_A)
  305.                 LD (WR_FF),A
  306.                 OUT (0xFF),A
  307.                 AND 3
  308.                 LD (MASK_WRK_DRV),A             ; номер дисковода
  309.                 INC A
  310.                 LD B,A
  311.                 LD A,%10000000
  312. .L1             RLCA
  313.                 DJNZ .L1
  314.                 LD (MASK_MNT_DRV),A             ; маска смонтированного дисковода
  315.                 RET
  316.  
  317. ; запись "A" в порт (C)
  318. W_OUTCA         LD A,(REG_A)
  319. W_OUTCA1        LD D,A
  320.                 LD BC,(REG_C)                   ; если порт не TR-DOS
  321.                 LD A,C
  322. ; определение в какой порт запись
  323.                 CP 0x1F
  324.                 JP Z,W_OUT1F
  325.                 CP 0x3F
  326.                 JR Z,W_OUT3F
  327.                 CP 0x5F
  328.                 JR Z,W_OUT5F
  329.                 CP 0x7F
  330.                 JR Z,W_OUT7F
  331.                 CP 0xFF
  332.                 JR Z,W_OUTFF
  333.                 CP LOW (WIN_A0)
  334.                 JR Z,W_OUTCA3
  335. W_OUTCA4        OUT (C),D
  336.                 RET
  337.  
  338. ; запись в порты ATM/PENTEVO
  339. W_OUTCA3        LD A,B
  340.                 LD HL,BB_CPU1
  341.                 CP HIGH (WIN_A1)
  342.                 JR Z,W_OUTCA2
  343.                 CP HIGH (WIN_P2)
  344.                 JR Z,W_OUTCA2
  345.                 LD HL,BB_CPU2
  346.                 CP HIGH (WIN_A2)
  347.                 JR Z,W_OUTCA2
  348.                 CP HIGH (WIN_P2)
  349.                 JR NZ,W_OUTCA4
  350. W_OUTCA2        LD E,B
  351.                 PUSH DE
  352.                 PUSH HL
  353.                 CALL READ_WCPU12
  354.                 POP HL
  355.                 POP DE
  356.                 LD (HL),D
  357.                 INC HL
  358.                 LD (HL),E
  359.                 JP WRITE_WCPU12
  360.  
  361. ; запись "D" в порт (C)
  362. W_OUTCD         LD A,(IREG_D)
  363.                 JR W_OUTCA1
  364.  
  365. ; передача байта, команда OUTI
  366. W_OUTI          LD HL,(BUFF_SECT)
  367.                 EXX
  368.                 LD A,(HL)
  369.                 INC HL
  370.                 EXX
  371.                 LD (HL),A
  372.                 INC HL
  373.                 LD (BUFF_SECT),HL
  374.                 RET
  375.  
  376. ; чтение порта 0x1F
  377. W_IN1F          LD A,(WR_1F)
  378.                 AND %11110000
  379.                 CP 0x10
  380.                 JR C,.L1
  381.                 CP 0x20
  382.                 JR C,.L3
  383.                 CP 0x80
  384.                 JR C,.L5
  385.                 CP 0xD0
  386.                 JR Z,.L1
  387.                 XOR A
  388.                 JR .L2
  389.  
  390. .L5             LD A,(PORT_3F)
  391.                 AND A
  392.                 JR NZ,.L1
  393.                 LD A,%00100100
  394.                 JR .L6
  395.  
  396. .L3             LD A,(.INDEX)
  397.                 XOR %00000100
  398.                 JR .L4
  399.  
  400. .L1             LD A,0x24
  401. .INDEX          EQU $-1
  402. .L4             XOR %00000010
  403. .L6             LD (.INDEX),A
  404. .L2             LD (RD_1F),A
  405.                 LD (REG_A),A
  406.                 RET
  407.  
  408. ; чтение порта 0x3F
  409. W_IN3F          LD A,(PORT_3F)
  410.                 LD (REG_A),A
  411.                 RET
  412.  
  413. ; чтение порта 0x5F
  414. W_IN5F          LD A,(PORT_5F)
  415.                 LD (REG_A),A
  416.                 RET
  417.  
  418. ; чтение порта 0x7F
  419. W_IN7F          LD A,(PORT_7F)
  420.                 LD (REG_A),A
  421.                 RET
  422.  
  423. ; чтение порта 0xFF
  424. W_INFF          LD A,(RD_FF)
  425.                 LD (REG_A),A
  426.                 RET
  427.  
  428. ; чтение в "H" из (С)
  429. W_INHC          LD A,(REG_C)
  430. ; определение из какого порта чтение
  431. W_INHC1         CP 0x1F
  432.                 JR NZ,W_INHC2
  433.                 LD A,(RD_1F)
  434.                 LD (REG_H),A
  435.                 RET
  436.  
  437. W_INHC2         CP 0x3F
  438.                 JR NZ,W_INHC3
  439.                 LD A,(PORT_3F)
  440.                 LD (REG_H),A
  441.                 RET
  442.        
  443. W_INHC3         CP 0x5F
  444.                 JR NZ,W_INHC4
  445.                 LD A,(PORT_5F)
  446.                 LD (REG_H),A
  447.                 RET
  448.        
  449. W_INHC4         CP 0x7F
  450.                 JR NZ,W_INHC5
  451.                 LD A,(PORT_7F)
  452.                 LD (REG_H),A
  453.                 RET
  454.        
  455. W_INHC5         CP 0xFF
  456.                 JR NZ,W_INHC6
  457.                 LD A,(WR_FF)
  458.                 LD (REG_H),A
  459.                 RET
  460.  
  461. W_INHC6         LD BC,(REG_C)
  462.                 IN A,(C)
  463.                 LD (REG_H),A
  464.                 RET
  465.  
  466. ; чтение INI
  467. W_INI           LD A,(RD_1F)
  468.                 LD HL,(REG_L)
  469.                 LD (HL),A
  470.                 INC HL
  471.                 DEC B
  472.                 LD (REG_L),HL
  473.                 RET
  474.  
  475. ;[ЧТЕНИЕ СЕКТОРА ИЛИ ПОРТОВ]
  476. READ_SEC_       LD A,(WR_1F)
  477.                 AND 0x0F0
  478.                 CP 0x80
  479.                 JP C,W_OUT1F.INFF_BIT6
  480.                 CP 0xC0
  481.                 JR NZ,READ_SEC_1
  482.                 LD A,(PORT_3F)
  483.                 LD HL,(REG_L)
  484.                 LD (HL),A
  485.                 INC HL
  486.                 DEC B
  487.                 LD A,(PORT_5F)
  488.                 LD (HL),A
  489.                 INC HL
  490.                 DEC B
  491.                 LD (REG_L),HL
  492.                 RET
  493.  
  494. ; чтение/запись сектора
  495. ; IXL = 0 - чтение, = FF - запись
  496. READ_WRITE_SEC  PUSH IX
  497.                 JR WRITE_SEC_1
  498.  
  499. ; чтение сектора
  500. READ_SEC_1      PUSH IX
  501.                 LD IXL,0
  502.                 JR WRITE_SEC_1
  503.  
  504. ; запись сектора
  505. WRITE_SEC_      PUSH IX
  506.                 LD IXL,0xFF
  507. WRITE_SEC_1     CALL READ_WCPU12
  508.                 CALL W_WR_RD_SECT
  509.                 LD IX,0x8090
  510.                 LD (REG_F),IX                   ; эмуляция флага успешного чтения/записи сектора
  511.                 CALL WRITE_WCPU12
  512.                 POP IX
  513.                 RET
  514.  
  515. FIND_SECTOR     LD BC,WIN_A1
  516.                 LD A,0x40
  517.                 OUT (C),A
  518.                 LD B,HIGH (WIN_P1)
  519.                 LD A,RAM_RAMDISK
  520.                 OUT (C),A                       ; страница заголовков рамдиска
  521.                 LD A,(PORT_3F)                  ; взяли номер трека
  522.                 ADD A,A                         ; сторон 2
  523.                 LD C,A
  524.                 LD A,(WR_FF)
  525.                 AND 0x10                        ; проверка какая сторона диска
  526.                 JR NZ,.L1
  527.                 INC C                           ; для стороны 1
  528. .L1             LD B,HIGH (CPU1) + 2            ; адрес начала инфы о секторах на дорожке
  529.                 LD A,(PORT_5F)                  ; взяли номер сектора
  530.                 LD L,A
  531.                 LD H,0
  532. .L3             LD A,(BC)
  533.                 LD D,A                          ; взяли номер сектора
  534.                 INC B
  535.                 LD A,(BC)
  536.                 LD E,A                          ; взяли размер сектора
  537.                 INC B
  538.                 LD A,D
  539.                 AND A
  540.                 SCF
  541.                 RET Z
  542.                 LD A,L
  543.                 CP D
  544.                 RET Z
  545.                 LD A,E
  546.                 ADD A,H
  547.                 LD H,A
  548.                 JR .L3
  549.  
  550. ; чтение или запись сектора рамдиска
  551. W_WR_RD_SECT    LD A,(WR_FF)
  552.                 AND 3
  553.                 INC A
  554.                 LD B,A
  555.                 LD A,%10000000
  556. .L1             RLCA
  557.                 DJNZ .L1
  558.                 LD B,A
  559.                 LD A,(COPY_VIRT_BITS)
  560.                 AND B
  561.                 JP NZ,WR_RD_SEC_M               ; работа с примонтированным образом
  562.                 CALL FIND_SECTOR
  563.                 JR NC,.L2
  564. ; сектор не найден, на выход
  565.                 LD A,0x10                       ; устанавливаем ошибку ВГ сектор не найден
  566.                 JP W_IN1F.L2                   
  567.  
  568. .L2             LD A,E
  569.                 RRCA
  570.                 LD (PORT_7F),A                  ; размер найденного сектора
  571.                 LD L,0
  572.                 LD E,L
  573.                 SRL H
  574.                 RR L                            ; HL = смещение в блоках до найденного сектора
  575.                 LD B,HIGH (CPU1)
  576.                 LD A,(BC)
  577.                 LD D,A
  578.                 ADD HL,DE                       ; HL = смещение от начала страницы в блоках
  579.                 INC B
  580.                 LD A,(BC)
  581.                 LD C,A                          ; смещение в страницах от начала рамдиска
  582.                 LD A,H
  583.                 CP HIGH (CPU1)
  584.                 JR C,.L5
  585.                 SUB 0x40
  586.                 LD H,A
  587.                 INC C
  588. ; HL = смещение в странице до начала сектора
  589. .L5             LD A,C                          ; смещение до номера страницы, где указанный сектор начинается
  590.                 ADD A,RAM_DATARAMD              ; прибавили номер начала рамдиск и +1. в 0 странице рамдиска описатели секторов
  591.                 LD IXH,A                        ; сохранили номер вычисленной страницы
  592.                 LD DE,(REG_L)
  593.                 LD BC,(BB_CPU1)
  594.                 LD A,C
  595.                 LD C,LOW (WIN_A0)
  596.                 OUT (C),A                       ; вернули стандартную 5 страницу
  597. .S9             LD A,D                          ; проверка границы откуда/куда копировать
  598.                 CP HIGH (CPU2)
  599.                 PUSH DE
  600.                 LD DE,CPU1+HIGH (WIN_P1)
  601.                 LD BC,WIN_A1                    ; если верхние 32кб озу, то нужно включить в 1 окне проецирования
  602.                 JR NC,.S1
  603.                 LD DE,CPU2+HIGH (WIN_P2)
  604.                 LD B,HIGH (WIN_A2)              ; если нижние 32кб озу, то нужно включить во 2 окне проецирования
  605. .S1             LD A,0x40
  606.                 OUT (C),A
  607.                 LD B,E
  608.                 LD A,IXH                        ; номер вычисленной страницы озу
  609.                 OUT (C),A                       ; включили вычисленную страницу
  610.                 LD B,D                          ; старший байт адреса начала включенной страницы
  611.                 POP DE
  612.                 LD A,B
  613.                 ADD A,H
  614.                 LD H,A
  615.                 LD A,IXL
  616.                 AND A
  617.                 JR NZ,.I1
  618.                 LD A,D
  619.                 INC A
  620.                 JR NZ,.I1
  621.                 LD A,E
  622.                 AND A
  623.                 JR Z,.I1
  624.                 NEG
  625.                 LD C,A
  626.                 LD B,0
  627.                 LDIR
  628.                 NEG
  629.                 LD C,A
  630. .I2             EX DE,HL
  631.                 ADD HL,BC
  632.                 EX DE,HL
  633.                 ADD HL,BC
  634.                 LD A,(PORT_7F)
  635.                 JP .S8_
  636.  
  637. .I1             LD A,D
  638.                 CP HIGH (CPU1)
  639.                 JR NC,.I3
  640.                 LD A,(PORT_7F)
  641.                 AND A
  642.                 LD BC,0x80
  643.                 JR Z,.I2
  644.                 LD BC,0x100
  645.                 JR .I2
  646.  
  647. .I3             CP HIGH (CPU2)                  ; проверка перехода границы страниц
  648.                 JP NC,.S3                       ; если выше то сразу копируем
  649.                 CP HIGH (CPU2)-1
  650.                 JP C,.S3                        ; если ниже так же сразу копируем
  651.                 LD A,E
  652.                 AND A                           ; если сектор полностью укладывется до границы, то сразу копируем
  653.                 JR Z,.S3                        ; иначе принудительно копируем в два приема
  654.                 LD A,IXL                        ; чтение или запись?
  655.                 AND A
  656.                 LD A,E                          ; младший байт адрес в блоке
  657.                 JR Z,.S4
  658.                 EX DE,HL                        ; для записи меняем направление
  659. .S4             NEG
  660.                 LD C,A                          ; копируем остаток до конца блока
  661.                 LD B,0
  662.                 LDIR
  663.                 NEG
  664.                 PUSH AF                         ; спрятали сколько осталось копировать из начала следующего блока
  665.                 LD BC,(BB_CPU2)
  666.                 LD A,C
  667.                 LD C,LOW (WIN_A0)
  668.                 OUT (C),A
  669.                 LD B,HIGH (WIN_A1)
  670.                 LD A,0x40
  671.                 OUT (C),A
  672.                 LD B,HIGH (WIN_P1)
  673.                 LD A,IXH
  674.                 OUT (C),A                       ; вычисленную страницу включаем в 1 окне проецирования
  675.                 LD A,IXL                        ; чтение или запись
  676.                 AND A
  677.                 JR Z,.S5
  678.                 LD A,D                          ; для записи
  679.                 SUB 0x40                        ; изменили адрес куда копировать на другое окно проецирования
  680.                 LD D,A
  681.                 JR .S6
  682.  
  683. .S5             LD A,H                          ; для чтения  
  684.                 SUB 0x40                        ; изменили адрес куда копировать на другое окно проецирования
  685.                 LD H,A
  686. .S6             POP AF
  687.                 LD C,A                          ; сколько осталось скопировать байт
  688.                 LD B,0
  689.                 LDIR
  690.                 LD A,(PORT_7F)
  691.                 JR .S8_
  692.  
  693. .S3             LD A,IXL                        ; чтение или запись
  694.                 AND A
  695.                 JR Z,.S7
  696.                 EX DE,HL                        ; для записи меняем направление
  697. .S7             LD A,(PORT_7F)
  698.                 AND A
  699.                 JR NZ,.S8
  700.                 CALL COPYHBLOCK                 ; для сектора размером 128 байт копируем половину и выходим
  701. .ECOPY_BLOCK    LD A,IXL
  702.                 AND A
  703.                 JR Z,.ECOPY_BLOCK1
  704.                 EX DE,HL
  705. .ECOPY_BLOCK1   LD (REG_L),DE
  706.                 RET
  707.  
  708. .S8             CALL COPY_BLOCK                 ; для сектора 256 байт копируем весь и выходим
  709. .S8_            DEC A
  710.                 JR Z,.ECOPY_BLOCK
  711.                 LD (PORT_7F),A
  712.                 LD A,IXL
  713.                 AND A
  714.                 JR Z,.S0
  715.                 EX DE,HL
  716. .S0             LD A,0x3F
  717.                 AND H
  718.                 LD H,A
  719.                 JP .S9
  720.  
  721. CP_TYPEDRIVE    PUSH BC
  722.                 PUSH HL
  723.                 LD H,VIRT_REAL_DRIVE
  724.                 CALL READCMOS
  725.                 POP HL
  726.                 AND 3
  727.                 LD B,A
  728.                 LD A,(TRD_5CF6)
  729.                 CP B
  730.                 POP BC
  731.                 RET
  732.  
  733. ; установка переменных текущего привода
  734. SET_DRIVENAME   LD H,VIRT_REAL_DRIVE
  735.                 CALL READCMOS
  736.                 RRCA
  737.                 RRCA
  738.                 AND 3
  739.                 LD (TRD_5D19),A
  740.                 LD (TRD_5CF6),A
  741.                 OR 0x3C
  742.                 LD (TRD_5D16),A
  743.                 RET
  744.  
  745. ; форматирование ram диска
  746. FORMAT_RAM      LD A,(TRD_5CF6)
  747.                 LD B,A
  748.                 INC B
  749.                 LD A,%00001000
  750.                 RLCA
  751.                 DJNZ $-1
  752.                 LD B,A
  753. ;               LD A,(COPY_VIRT_BITS)
  754.                 RST8D _MOUNTER,_GET_VIRT_BITS
  755.                 LD (COPY_VIRT_BITS),A
  756.                 AND B
  757.                 JR NZ,FORMAT_RAM3               ; если бит=1 формат примонтированного образа
  758.                 CALL CP_TYPEDRIVE
  759.                 RET NZ                          ; выход для формата рельного диска
  760.                 CALL CREATE_TRDTABL             ; формат рамдиска
  761.                 XOR A
  762.                 RET
  763.  
  764. FORMAT_RAM3     LD HL,TRD_5D25
  765.                 LD DE,TRD_5D26
  766.                 LD BC,0xFF
  767.                 LD (HL),B
  768.                 LDIR
  769.                 LD D,B
  770.                 LD E,B
  771.                 LD B,0x10
  772. FORMAT_RAM1     PUSH BC
  773.                 PUSH DE
  774.                 LD B,1
  775.                 LD HL,TRD_5D25
  776.                 CALL COM_06
  777.                 POP DE
  778.                 POP BC
  779.                 INC E
  780.                 DJNZ FORMAT_RAM1
  781.                 XOR A
  782.                 RET
  783.  
  784. ; проверка наличия маркера рамдиска
  785. CMP_RAM_DISK    CALL READ_WCPU12
  786.                 LD BC,WIN_P1
  787.                 LD A,RAM_RAMDISK
  788.                 OUT (C),A
  789.                 LD HL,CPU1+0x3FFF
  790.                 LD D,(HL)
  791.                 DEC H
  792.                 LD E,(HL)                       ; взяли байты для проверки маркера
  793.                 CALL WRITE_WCPU12
  794.                 LD HL,"RD"
  795.                 AND A
  796.                 SBC HL,DE
  797.                 RET Z                           ; если маркер на месте, то рамдиск не создаем
  798. ; создание чистого рамдиска
  799. CREATE_TRDTABL  LD BC,WIN_P1
  800.                 LD A,RAM_RAMDISK                ; нужна страница начала рамдиска, где будет таблица описателей
  801.                 OUT (C),A
  802.                 LD HL,CPU1
  803.                 PUSH HL
  804.                 LD DE,CPU1+1
  805.                 LD BC,0x3FFF
  806.                 LD (HL),L
  807.                 LDIR                            ; очистили страницу
  808.                 POP DE                          ; адрес начала
  809.                 LD HL,0                         ; смещение в блоках и страницах
  810.                 LD A,0xA0
  811. ELT2            PUSH AF
  812.                 LD BC,0x1000                    ; счетчик номеров секторов и их номера
  813.                 LD A,L
  814.                 RRCA
  815.                 RRCA
  816.                 LD (DE),A                       ; смещение в блоках дорожки в странице
  817.                 INC D
  818.                 LD A,H
  819.                 LD (DE),A                       ; смещение в страницах до дорожки
  820.                 INC D
  821. ELT1            INC C
  822.                 LD A,C
  823.                 LD (DE),A                       ; номер сектора
  824.                 INC D
  825.                 LD A,2
  826.                 LD (DE),A                       ; размер сектора
  827.                 INC D
  828.                 DJNZ ELT1                       ; вносим в таблицу все номера секторов с размерами
  829.                 LD D,HIGH (CPU1)                ; вернули указатель в начало
  830.                 INC E                           ; для следующей дорожки
  831.                 LD BC,0x40
  832.                 ADD HL,BC                       ; переход к следующей дорожке
  833.                 POP AF
  834.                 DEC A
  835.                 JR NZ,ELT2                      ; повторяем для всех дорожек
  836.                 LD HL,CPU1+0x3FFF
  837.                 LD (HL),"R"                     ; вносим маркер рамдиска
  838.                 DEC H
  839.                 LD (HL),"D"
  840.                 LD BC,WIN_P1
  841.                 LD A,RAM_DATARAMD
  842.                 OUT (C),A
  843.                 LD HL,CPU1
  844.                 LD DE,CPU1+1
  845.                 LD BC,0x0FFF
  846.                 LD (HL),L
  847.                 LDIR
  848.                 LD HL,DSKINFO
  849.                 LD DE,CPU1+0x8E1
  850.                 LD BC,DSK_END-DSKINFO
  851.                 LDIR
  852.                 LD BC,WIN_A1
  853.                 LD A,0x7A
  854.                 OUT (C),A
  855.                 RET
  856.  
  857. ; восстановление конфигурации окон проецирования 1,2
  858. WRITE_WCPU12    LD BC,(BB_CPU1)
  859.                 LD A,C
  860.                 LD C,LOW (WIN_A0)
  861.                 OUT (C),A
  862.                 LD BC,(BB_CPU2)
  863.                 LD A,C
  864.                 LD C,LOW (WIN_A0)
  865.                 OUT (C),A
  866.                 RET
  867.  
  868. ; чтение конфигурации окон проецирования 1,2
  869. READ_WCPU12     LD BC,RD_RAMNROM
  870.                 IN L,(C)                        ; биты RAM & ROM
  871.                 INC B
  872.                 IN H,(C)                        ; биты DOS & 7FFD
  873.                 ADD HL,HL
  874.                 LD B,HIGH (RD_1WINA1)
  875.                 IN A,(C)
  876.                 CP 0xC0
  877.                 JR NC,RST30_01
  878.                 LD E,A
  879.                 LD D,HIGH (WIN_P1)
  880.                 JR RST30_02
  881.  
  882. RST30_01        RLCA
  883.                 RLCA
  884.                 SLA L
  885.                 RRA
  886.                 SLA H
  887.                 RRA
  888.                 LD E,A
  889.                 LD D,HIGH (WIN_A1)
  890. RST30_02        LD (BB_CPU1),DE
  891.                 INC B
  892.                 IN A,(C)
  893.                 CP 0xC0
  894.                 JR NC,RST30_03
  895.                 LD E,A
  896.                 LD D,HIGH (WIN_P2)
  897.                 JR RST30_04
  898.  
  899. RST30_03        RLCA
  900.                 RLCA
  901.                 SLA L
  902.                 RRA
  903.                 SLA H
  904.                 RRA
  905.                 LD E,A
  906.                 LD D,HIGH (WIN_A2)
  907. RST30_04        LD (BB_CPU2),DE
  908.                 RET
  909.  
  910. DISK_NONE       PUSH HL
  911.                 PUSH BC
  912.                 CALL READ_WCPU12
  913.                 LD BC,WIN_A1
  914.                 LD A,0x40
  915.                 OUT (C),A
  916.                 LD B,HIGH (WIN_P1)
  917.                 LD A,RAM_RAMDISK
  918.                 OUT (C),A
  919.                 LD HL,CPU1+0x3FFF
  920.                 LD A,(HL)
  921.                 DEC H
  922.                 CP "R"
  923.                 SCF
  924.                 JR NZ,DISK_NONE1
  925.                 LD A,(HL)
  926.                 CP "D"
  927.                 SCF
  928.                 JR NZ,DISK_NONE1
  929.                 XOR A
  930. DISK_NONE1      PUSH AF
  931.                 CALL WRITE_WCPU12
  932.                 POP AF
  933.                 POP BC
  934.                 POP HL
  935.                 RET
  936.