Subversion Repositories pentevo

Rev

Rev 1186 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. ; LAST UPDATE: 21.03.2025 savelij
  3.  
  4. ; ((out&0ffff)==37f7)&&((val&0ff)==1)
  5. ; ((out&0ffff)==77f7)&&((val&0ff)==1)
  6. ; ((out&0ffff)==0b7f7)&&((val&0ff)==1)
  7. ; ((out&0ffff)==0f7f7)&&((val&0ff)==1)
  8. ; ((M(5CF4)==2)&&(M(5CF5)==1B))
  9. ; (((M(5CF4)==2)&&(M(5CF5)==1B))&&(SP<4000))
  10. ; ((OUT&0FFFF)==1F)|((OUT&0FFFF)==3F)|((OUT&0FFFF)==7F)
  11.  
  12.                 include macros.a80
  13.                 include global_vars.a80
  14.                 include define.a80
  15.                 include evodos_vars.a80
  16.                 include version.a80
  17.  
  18. STACK           EQU 0x0DFF
  19.  
  20. OLD_IF          EQU STACK - WORD * 2
  21. OLD_AF          EQU STACK - WORD
  22.  
  23.  BITMASK RDWR,          7                       ; 1-запись, 0-чтение
  24.  
  25. ; команда выхода и переход на обработчик
  26. JP_EMU          MACRO ADDRESS
  27.                 DB ADDRESS-$ DUP 0
  28.                 OUT (EXIT_PORT),A
  29.                 JP ADR_ADDRESS
  30.                 ENDM
  31.  
  32. ; генерация адресов для таблицы
  33. LABEL_GEN       MACRO ADDRESS
  34. _ADDRESS        EQU ($ - TABLE_VIRT) / 4
  35.                 DW ADDRESS,ADR_ADDRESS.WORK
  36.                 ENDM
  37.  
  38. ; переход на обработчик с кодом адреса
  39. EMU_JUMP        MACRO ADDRESS
  40. ADR_ADDRESS     EQU $
  41.                 LD (OLD_AF + 1),A
  42.                 LD A,_ADDRESS
  43.                 JP WORKER
  44.  
  45. .WORK           EQU $
  46.                 ENDM
  47.  
  48.                 ORG 0
  49.                 DB "Emu TR-DOS v",VERS_DOS,"Build: "
  50.                 TEXTTIME
  51.                 DB " "
  52.                 TEXTDATE
  53.  
  54.                 DB 0x0038 - $ DUP 0
  55.                 EI
  56.                 RET
  57.  
  58.                 DB 0x006F - $ DUP 0
  59.                 JP (HL)
  60.  
  61.         JP_EMU 0x02BE                           ; OUT      (0xFF), A
  62.  
  63.                 DB 0x0801 - $ DUP 0
  64. ;таблица адресов перехвата и вызыватора обработчиков
  65. TABLE_VIRT
  66.         LABEL_GEN 0x02BE                        ; OUT      (0xFF), A
  67.         LABEL_GEN 0x1E3A                        ; OUT      (0x3F), A
  68.         LABEL_GEN 0x1FDD                        ; IN    A, (0x1F)
  69.         LABEL_GEN 0x1FF3                        ; OUT      (0xFF), A
  70.         LABEL_GEN 0x2000                        ; OUT      (0x1F), A
  71.         LABEL_GEN 0x2076                        ; IN    A, (0x1F)
  72.         LABEL_GEN 0x2085                        ; OUT      (0x3F), A
  73.         LABEL_GEN 0x208D                        ; OUT      (0x5F), A
  74.         LABEL_GEN 0x2093                        ; OUT      (0x1F), A
  75.         LABEL_GEN 0x2099                        ; IN    A, (0x1F)
  76.         LABEL_GEN 0x20B1                        ; IN    A, (0xFF)
  77.         LABEL_GEN 0x20B8                        ; OUT      (C),    D
  78.         LABEL_GEN 0x2740                        ; IN    A, (0x1F)
  79.         LABEL_GEN 0x2748                        ; OUT      (0x7F), A
  80.         LABEL_GEN 0x2A53                        ; OUT      (C),    A
  81.         LABEL_GEN 0x2A71                        ; OUT      (0xFF), A MAGIC
  82.         LABEL_GEN 0x2A77                        ; IN    A, (0x1F)    MAGIC
  83.         LABEL_GEN 0x2AD9                        ; OUT      (OxFF), A MAGIC
  84.         LABEL_GEN 0x2B25                        ; IN    A, (0x5F)    MAGIC
  85.         LABEL_GEN 0x2C07                        ; IN    A, (0x5F)    MAGIC
  86.         LABEL_GEN 0x2CD8                        ; IN    A, (0x5F)    MAGIC
  87.         LABEL_GEN 0x2D75                        ; OUT      (0x5F), A MAGIC
  88.         LABEL_GEN 0x2D80                        ; OUT      (0x1F), A MAGIC
  89.         LABEL_GEN 0x2D87                        ; IN    A, (0x1F)    MAGIC
  90.         LABEL_GEN 0x2F0C                        ; OUT      (0xFF), A MAGIC
  91.         LABEL_GEN 0x2F1D                        ; OUT      (0x5F), A MAGIC
  92.         LABEL_GEN 0x2F28                        ; OUT      (0x1F), A MAGIC
  93.         LABEL_GEN 0x2F2F                        ; IN    A, (0x1F)    MAGIC
  94.         LABEL_GEN 0x2F3C                        ; OUT      (0xFF), A MAGIC
  95.         LABEL_GEN 0x2F4D                        ; OUT      (0xFF), A MAGIC
  96.         LABEL_GEN 0x2F50                        ; OUT      (0x7F), A MAGIC
  97.         LABEL_GEN 0x2F57                        ; OUT      (0x1F), A MAGIC
  98.         LABEL_GEN 0x2F59                        ; IN    A, (0xFF)
  99.         LABEL_GEN 0x2FB1                        ; OUT      (0xFF), A
  100.         LABEL_GEN 0x2FC3                        ; OUT      (0x1F), A
  101.         LABEL_GEN 0x3C30                        ; IN    A, (0x1F)
  102.         LABEL_GEN 0x3D4D                        ; OUT      (0xFF), A
  103.         LABEL_GEN 0x3D9A                        ; OUT      (0x1F), A
  104.         LABEL_GEN 0x3DA6                        ; IN    A, (0xFF)
  105.         LABEL_GEN 0x3DB5                        ; IN    A, (0x1F)
  106.         LABEL_GEN 0x3DBA                        ; IN    A, (0x1F)
  107.         LABEL_GEN 0x3DD5                        ; OUT      (0xFF), A
  108.         LABEL_GEN 0x3E30                        ; IN    A, (0x1F)
  109.         LABEL_GEN 0x3E3A                        ; IN    A, (0x1F)
  110.         LABEL_GEN 0x3E44                        ; OUT      (0x7F), A
  111.         LABEL_GEN 0x3E4C                        ; OUT      (0x7F), A
  112.         LABEL_GEN 0x3E50                        ; IN    A, (0x3F)
  113.         LABEL_GEN 0x3E78                        ; IN    A, (0x3F)
  114.         LABEL_GEN 0x3E7E                        ; OUT      (0x3F), A
  115.         LABEL_GEN 0x3E87                        ; IN    A, (0x3F)
  116.         LABEL_GEN 0x3E95                        ; OUT      (0x3F), A
  117.         LABEL_GEN 0x3EB5                        ; IN    A, (0x1F)
  118.         LABEL_GEN 0x3EBC                        ; IN    A, (0x3F)
  119.         LABEL_GEN 0x3EC9                        ; OUT      (0x1F), A
  120.         LABEL_GEN 0x3ECE                        ; IN    A, (0xFF)
  121.         LABEL_GEN 0x3EDF                        ; OUT      (0x1F), A
  122.         LABEL_GEN 0x3EF3                        ; IN    H, (C)
  123.         LABEL_GEN 0x3EF5                        ; IN    A, (0xFF)
  124.         LABEL_GEN 0x3EFE                        ; IN    A, (0x7F)
  125.         LABEL_GEN 0x3F1B                        ; OUT      (0x5F), A
  126.         LABEL_GEN 0x3F25                        ; OUT      (0x1F), A
  127.         LABEL_GEN 0x3F33                        ; IN    A, (0x1F)
  128.         LABEL_GEN 0x3F4D                        ; OUT      (0x1F), A
  129.         LABEL_GEN 0x3F55                        ; IN    A, (0x3F)
  130.         LABEL_GEN 0x3F5A                        ; Ix    A, (0x5F)
  131.         LABEL_GEN 0x3F69                        ; IN    A, (0x3F)
  132.         LABEL_GEN 0x3F72                        ; IN    A, (0x5F)
  133.         LABEL_GEN 0x3FBC                        ; IN    A, (0xFF)
  134.         LABEL_GEN 0x3FCA                        ; IN    A, (0xFF)
  135.         LABEL_GEN 0x3FD1                        ; OUTI
  136.         LABEL_GEN 0x3FD7                        ; IN    A, (0xFF)
  137.         LABEL_GEN 0x3FE5                        ; IN    A, (0xFF)
  138.         LABEL_GEN 0x3FEC                        ; INI
  139.         LABEL_GEN 0x3FF0                        ; OUT      (C),    A
  140.         LABEL_GEN 0x3FF3                        ; IN    A, (C)
  141.  
  142. ; вызываторы перехвата
  143.         EMU_JUMP 0x02BE                         ; OUT (0xFF),A
  144.                 JP OUT_FF
  145.  
  146.         EMU_JUMP 0x1E3A                         ; OUT (0x3F),A
  147.                 JP OUT_3F
  148.  
  149.         EMU_JUMP 0x1FDD                         ; IN A,(0x1F)
  150.                 JP IN_1F
  151.  
  152.         EMU_JUMP 0x1FF3                         ; OUT (0xFF),A
  153.                 JP OUT_FF
  154.  
  155.         EMU_JUMP 0x2000                         ; OUT (0x1F),A
  156.                 JP OUT_1F
  157.  
  158.         EMU_JUMP 0x2076                         ; IN A,(0x1F)
  159.                 JP IN_1F
  160.  
  161.         EMU_JUMP 0x2085                         ; OUT (0x3F),A
  162.                 JP OUT_3F
  163.  
  164.         EMU_JUMP 0x208D                         ; OUT (0x5F),A
  165.                 JP OUT_5F
  166.  
  167.         EMU_JUMP 0x2093                         ; OUT (0x1F),A
  168.                 JP OUT_1F
  169.  
  170.         EMU_JUMP 0x2099                         ; IN A,(0x1F)
  171.                 JP IN_1F
  172.  
  173.         EMU_JUMP 0x20B1                         ; IN A,(0xFF)
  174.                 JP IN_FF
  175.  
  176.         EMU_JUMP 0x20B8                         ; OUT (C),D
  177.                 JP OUT_C_D
  178.  
  179.         EMU_JUMP 0x2740                         ; IN A,(0x1F)
  180.                 JP IN_1F
  181.  
  182.         EMU_JUMP 0x2748                         ; OUT (0x7F),A
  183.                 JP OUT_7F
  184.  
  185.         EMU_JUMP 0x2A53                         ; OUT (C),A
  186.                 JP OUT_C_A
  187.  
  188.         EMU_JUMP 0x2A71                         ; OUT (0xFF),A
  189.                 JP OUT_FF
  190.  
  191.         EMU_JUMP 0x2A77                         ; IN A,(0x1F)
  192.                 JP IN_1F
  193.  
  194.         EMU_JUMP 0x2AD9                         ; OUT (0xFF),A
  195.                 JP OUT_FF
  196.  
  197.         EMU_JUMP 0x2B25                         ; IN A,(0x5F)
  198.                 JP IN_5F
  199.  
  200.                 DB 0x09FF - $ DUP 0
  201.                 DW 0xFFFF
  202.  
  203.         EMU_JUMP 0x2C07                         ;IN A,(0x5F)
  204.                 JP IN_5F
  205.  
  206.         EMU_JUMP 0x2CD8                         ; IN A,(0x5F)
  207.                 JP IN_5F
  208.  
  209.         EMU_JUMP 0x2D75                         ; OUT (0x5F),A
  210.                 JP OUT_5F
  211.  
  212.         EMU_JUMP 0x2D80                         ; OUT (0x1F),A
  213.                 JP OUT_1F
  214.  
  215.         EMU_JUMP 0x2D87                         ; IN A,(0x1F)
  216.                 JP IN_1F
  217.  
  218.         EMU_JUMP 0x2F0C                         ; OUT (0xFF),A
  219.                 JP OUT_FF
  220.  
  221.         EMU_JUMP 0x2F1D                         ; OUT (0x5F),A
  222.                 JP OUT_5F
  223.  
  224.         EMU_JUMP 0x2F28                         ; OUT (0x1F),A
  225.                 JP OUT_1F
  226.  
  227.         EMU_JUMP 0x2F2F                         ; IN A,(0x1F)
  228.                 JP IN_1F
  229.  
  230.         EMU_JUMP 0x2F3C                         ; OUT (0xFF),A
  231.                 JP OUT_FF
  232.  
  233.         EMU_JUMP 0x2F4D                         ; OUT (0xFF),A
  234.                 JP OUT_FF
  235.  
  236.         EMU_JUMP 0x2F50                         ; OUT (0x7F),A
  237.                 JP OUT_7F
  238.  
  239.         EMU_JUMP 0x2F57                         ; OUT (0x1F),A
  240.                 JP OUT_1F
  241.  
  242.         EMU_JUMP 0x2F59                         ; IN A,(0xFF)
  243.                 CALL IN_FF
  244.                 LD HL,EXIT_0x2F59
  245.                 LD (ADR_EXIT),HL
  246.                 JP UPDATE_AF
  247.  
  248.         EMU_JUMP 0x2FB1                         ; OUT (0xFF),A
  249.                 JP OUT_FF
  250.  
  251.         EMU_JUMP 0x2FC3                         ; OUT (0x1F),A
  252.                 JP OUT_1F
  253.  
  254.         EMU_JUMP 0x3C30                         ; IN A,(0x1F)
  255.                 JP IN_1F
  256.  
  257.         EMU_JUMP 0x3D4D                         ; OUT (0xFF),A
  258.                 JP OUT_FF
  259.  
  260.         EMU_JUMP 0x3D9A                         ; OUT (0x1F),A
  261.                 JP OUT_1F
  262.  
  263.         EMU_JUMP 0x3DA6                         ; IN A,(0xFF)
  264.                 JP IN_FF
  265.  
  266.         EMU_JUMP 0x3DB5                         ; IN A,(0x1F)
  267.                 JP IN_1F
  268.  
  269.         EMU_JUMP 0x3DBA                         ; IN A,(0x1F)
  270.                 JP IN_1F
  271.  
  272.         EMU_JUMP 0x3DD5                         ; OUT (0xFF),A
  273.                 JP OUT_FF
  274.  
  275.         EMU_JUMP 0x3E30                         ; IN A,(0x1F)
  276.                 JP IN_1F
  277.  
  278.         EMU_JUMP 0x3E3A                         ; IN A,(0x1F)
  279.                 JP IN_1F
  280.  
  281.         EMU_JUMP 0x3E44                         ; OUT (0x7F),A
  282.                 JP OUT_7F
  283.  
  284.         EMU_JUMP 0x3E4C                         ; OUT (0x7F),A
  285.                 JP OUT_7F
  286.  
  287.         EMU_JUMP 0x3E50                         ; IN A,(0x3F)
  288.                 JP IN_3F
  289.  
  290.         EMU_JUMP 0x3E78                         ; IN A,(0x3F)
  291.                 JP IN_3F
  292.  
  293.         EMU_JUMP 0x3E7E                         ; OUT (0x3F),A
  294.                 JP OUT_3F
  295.  
  296.         EMU_JUMP 0x3E87                         ; IN A,(0x3F)
  297.                 JP IN_3F
  298.  
  299.         EMU_JUMP 0x3E95                         ; OUT (0x3F),A
  300.                 JP OUT_3F
  301.  
  302.         EMU_JUMP 0x3EB5                         ; IN A,(0x1F)
  303.                 JP IN_1F
  304.  
  305.         EMU_JUMP 0x3EBC                         ; IN A,(0x3F)
  306.                 JP IN_3F
  307.  
  308.         EMU_JUMP 0x3EC9                         ; OUT (0x1F),A
  309.                 JP OUT_1F
  310.  
  311.         EMU_JUMP 0x3ECE                         ; IN A,(0xFF)
  312.                 JP IN_FF
  313.  
  314.         EMU_JUMP 0x3EDF                         ; OUT (0x1F),A
  315.                 JP OUT_1F
  316.  
  317.         EMU_JUMP 0x3EF3                         ; IN H,(C)
  318.                 JP IN_H_C
  319.  
  320.         EMU_JUMP 0x3EF5                         ; IN A,(0xFF)
  321.                 CALL IN_FF
  322.                 LD HL,EXIT_0x3EF5
  323.                 LD (ADR_EXIT),HL
  324. UPDATE_AF       LD A,(OLD_AF + 1)
  325.                 AND 0xC0
  326.                 PUSH AF
  327.                 POP HL
  328.                 LD (OLD_AF),HL
  329.                 RET
  330.  
  331.         EMU_JUMP 0x3EFE                         ; IN A,(0x7F)
  332.                 CALL OUT_1F.INFF_BIT6
  333.                 JP IN_7F
  334.  
  335.         EMU_JUMP 0x3F1B                         ; OUT (0x5F),A
  336.                 JP OUT_5F
  337.  
  338.         EMU_JUMP 0x3F25                         ; OUT (0x1F),A
  339.                 JP OUT_1F
  340.  
  341.         EMU_JUMP 0x3F33                         ; IN A,(0x1F)
  342.                 JP IN_1F
  343.  
  344.         EMU_JUMP 0x3F4D                         ; OUT (0x1F),A
  345.                 JP OUT_1F
  346.  
  347.         EMU_JUMP 0x3F55                         ; IN A,(0x3F)
  348.                 JP IN_3F
  349.  
  350.         EMU_JUMP 0x3F5A                         ; IN A,(0x5F)
  351.                 JP IN_5F
  352.  
  353.         EMU_JUMP 0x3F69                         ; IN A,(0x3F)
  354.                 JP IN_3F
  355.  
  356.         EMU_JUMP 0x3F72                         ; IN A,(0x5F)
  357.                 JP IN_5F
  358.  
  359.         EMU_JUMP 0x3FBC                         ; IN A,(0xFF)   ; запись сектора
  360.                 JP WRITE_SECTOR
  361.  
  362.         EMU_JUMP 0x3FCA                         ; IN A,(0xFF)   ; запись сектора
  363.                 JP WRITE_SECTOR
  364.  
  365.         EMU_JUMP 0x3FD1                         ; OUTI          ; запись сектора
  366.                 JP WRITE_SECTOR
  367.  
  368.         EMU_JUMP 0x3FD7                         ; IN A,(0xFF)   ; чтение сектора
  369.                 JP READ_SECTOR
  370. ;       EMU_JUMP 0x3FD7                         ; ожидание готовности чтения
  371. ;               JP WAIT_READ
  372.  
  373.         EMU_JUMP 0x3FE5                         ; IN A,(0xFF)   ; чтение сектора
  374.                 JP READ_SECTOR
  375.  
  376.         EMU_JUMP 0x3FEC                         ; INI           ; чтение сектора
  377.                 JP IN_INI
  378.  
  379.         EMU_JUMP 0x3FF0                         ; OUT (C),A
  380.                 LD BC,(OLD_BC)
  381.                 LD A,(OLD_AF+1)
  382.                 LD D,A
  383.                 JP WR_C_D
  384.  
  385.         EMU_JUMP 0x3FF3                         ; IN A,(C)
  386.                 LD BC,(OLD_BC)
  387.                 IN A,(C)
  388.                 PUSH AF
  389.                 POP HL
  390.                 LD (OLD_AF),HL
  391.                 RET
  392.  
  393. ; стек и обработчики
  394.                 DB STACK - $ DUP 0
  395.                 DW INT_BREAK
  396.  
  397. INT_BREAK       PUSH AF
  398.                 PUSH HL
  399.                 PUSH DE
  400.                 LD A,(FLAG_RW_BREAK)
  401.                 AND A
  402.                 JR NZ,.L1
  403.                 LD HL,(OLD_IF)
  404.                 LD L,0xFF
  405.                 LD E,(HL)
  406.                 INC HL
  407.                 LD D,(HL)
  408.                 LD HL,(OLD_SP)
  409.                 DEC HL
  410.                 LD (HL),D
  411.                 DEC HL
  412.                 LD (HL),E
  413.                 LD (OLD_SP),HL
  414.                 POP DE
  415.                 POP HL
  416.                 POP AF
  417.                 EI
  418.                 RET
  419.  
  420. .L1             PUSH BC
  421.                 LD (INT_SP),SP
  422.                 CALL READ_TMP_CPU12
  423.                 CALL WRITE_CPU12
  424.                 LD A,(OLD_PORT_BF)
  425.                 OUT (PEVO_CONF),A
  426.                 LD A,(OLD_IF + 1)
  427.                 LD I,A
  428.                 LD HL,(OLD_AF)
  429.                 PUSH HL
  430.                 POP AF
  431.                 LD HL,(OLD_SP)
  432.                 LD DE,0x2A71                    ; адрес возврата из обработчика прерывания внешней проги через OUT (0xFF),A
  433.                 DEC HL
  434.                 LD (HL),D
  435.                 DEC HL
  436.                 LD (HL),E
  437.                 DEC HL
  438.                 EX DE,HL
  439.                 LD HL,OLD_IF + 1
  440.                 LD H,(HL)
  441.                 LD L,0xFF
  442.                 LD C,(HL)
  443.                 INC HL
  444.                 LD B,(HL)
  445.                 EX DE,HL
  446.                 LD (HL),B
  447.                 DEC HL
  448.                 LD (HL),C
  449.                 LD SP,HL
  450.                 LD HL,(OLD_HL)
  451.                 LD DE,(OLD_DE)
  452.                 LD BC,(OLD_BC)
  453.                 LD A,(WR_FF)                    ; байтик для возврата через команду OUT (0xFF),A
  454.                 EI
  455.                 JP 0x2A53
  456.  
  457. INT_RET         LD SP,0
  458. INT_SP          EQU $-2
  459.                 IN A,(PEVO_CONF)
  460.                 LD (OLD_PORT_BF),A
  461.                 OR 1
  462.                 OUT (PEVO_CONF),A
  463.                 LD A,HIGH (STACK)
  464.                 LD I,A
  465.                 CALL WRITE_TMP_CPU12
  466.                 POP BC
  467.                 POP DE
  468.                 POP HL
  469.                 POP AF
  470.                 RET
  471.  
  472. ; выход из обработчика
  473. EXIT_PAGE_FE    LD A,(OLD_PORT_BF)
  474.                 OUT (PEVO_CONF),A               ; восстановление порта 0xBF
  475.                 LD A,(OLD_IF + 1)
  476.                 LD I,A
  477.                 LD HL,(OLD_AF)
  478.                 PUSH HL
  479.                 POP AF
  480.                 LD HL,0                         ; восстановление HL
  481. OLD_HL          EQU $-2
  482.                 LD DE,0                         ; восстановление DE
  483. OLD_DE          EQU $-2
  484.                 LD BC,0                         ; восстановление BC
  485. OLD_BC          EQU $-2
  486.                 LD SP,0                         ; восстановление SP
  487. OLD_SP          EQU $-2
  488.                 JP 0
  489. ADR_EXIT        EQU $-2        
  490.  
  491. ; вход в обработчик
  492. WORKER          LD (NUM_ADR),A
  493.                 LD (OLD_SP),SP
  494.                 LD SP,STACK - WORD
  495.                 PUSH AF
  496.                 EX (SP),HL
  497.                 LD A,L
  498.                 LD (OLD_AF),A
  499.                 POP HL
  500.                 LD A,I
  501.                 JP PE,.L1
  502.                 LD A,I
  503. .L1             PUSH AF                         ; IF
  504.                 IN A,(PEVO_CONF)
  505.                 LD (OLD_PORT_BF),A              ; порт BF
  506.                 OR 1
  507.                 OUT (PEVO_CONF),A
  508.                 LD A,HIGH (STACK)
  509.                 LD I,A
  510.                 LD (OLD_HL),HL
  511.                 LD (OLD_DE),DE
  512.                 LD (OLD_BC),BC
  513.                 LD HL,0
  514. NUM_ADR         EQU $-2
  515.                 ADD HL,HL
  516.                 ADD HL,HL
  517.                 LD DE,TABLE_VIRT
  518.                 ADD HL,DE
  519.                 LD E,(HL)
  520.                 INC HL
  521.                 LD D,(HL)                       ; DE-адрес возврата из обработчика
  522.                 INC HL
  523.                 LD (ADR_EXIT),DE
  524.                 LD E,(HL)
  525.                 INC HL
  526.                 LD D,(HL)                       ; DE-адрес обработчика
  527.                 PUSH DE
  528.                 LD HL,EXIT_PAGE_FE              ; код выхода из обработчика
  529.                 EX (SP),HL
  530.                 JP (HL)
  531.  
  532. ; чтение/запись примонтированного диска
  533. MOUNT_RW        DI
  534.                 LD A,(RDWR_MODE)
  535.                 AND M_RDWR
  536.                 LD L,A
  537.                 LD A,(WR_FF)
  538.                 AND 3
  539.                 OR L
  540.                 BIT B_RDWR,A
  541.                 PUSH AF                         ; флаг чтения/записи на стек
  542.                 LD HL,0x2A77
  543.                 PUSH HL                         ; адрес возврата на стек
  544.                 LD HL,MNT_RW + CPU1
  545.                 PUSH HL                         ; адрес вызова RST 8 для чтения/записи на стек
  546.                 JR Z,.L1
  547. ; запись, копируем в буфер сектор который будем записывать на смонтированный образ
  548.                 LD HL,(OLD_HL)
  549.                 LD DE,MNT_SECTOR
  550.                 CALL COPY_BLOCK
  551.                 LD (OLD_HL),HL
  552. ; переключаем паги для работы с маунтом
  553. .L1             PUSH AF
  554.                 LD BC,WIN_A1
  555.                 LD A,0x40
  556.                 OUT (C),A
  557.                 LD B,HIGH (WIN_P1)
  558.                 LD A,RAM_EVODOS
  559.                 OUT (C),A
  560.                 POP AF
  561. ; переставляем стек
  562.                 LD HL,CPU1
  563.                 ADD HL,SP
  564.                 LD SP,HL
  565.                 JP 0x2A53
  566.  
  567. ; чтение/запись сектора в образе
  568. MNT_RW          LD L,A
  569.                 LD A,(PORT_3F + CPU1)           ; взяли номер трека
  570.                 ADD A,A                         ; сторон 2
  571.                 LD D,A
  572.                 LD A,(WR_FF + CPU1)
  573.                 AND 0x10                        ; проверка какая сторона диска
  574.                 JR NZ,.L1
  575.                 INC D                           ; для стороны 1
  576. .L1             LD A,(PORT_5F + CPU1)           ; взяли номер сектора
  577.                 LD E,A                          ; D-трек, E-сектор
  578.                 LD A,L
  579.                 LD HL,MNT_SECTOR + CPU1
  580.         RST8 _MOUNTER,_RDWR_MOUNT
  581.                 JP 0x3D2F
  582.  
  583. ; возврат после чтения/записи в образе
  584. RET_MNT_RW      LD HL,-CPU1
  585.                 ADD HL,SP
  586.                 LD SP,HL
  587.                 CALL WRITE_CPU12
  588.                 POP AF
  589.                 RET NZ                          ; для записи выходим
  590. ; для чтения переносим сектор в указанный адрес
  591.                 LD HL,MNT_SECTOR                ; буфер откуда переносить
  592.                 LD DE,(OLD_HL)                  ; адрес куда переносить
  593.                 LD A,D
  594.                 CP 0x40                         ; чтение в адреса 0x0000...0x3FFF?
  595.                 JR NC,.L5
  596.                 CP 0x3F
  597.                 JR NZ,.L3                       ; если не 0x3Fxx, пропускаем
  598.                 LD A,E
  599.                 AND A
  600.                 JR Z,.L3                        ; для адрес 0x3F00 просто пропуск
  601. ; для смещения в адресе 0x3Fxx
  602.                 NEG
  603.                 LD C,A
  604.                 LD B,0
  605.                 ADD HL,BC                       ; сколько пропустить от начала буфера
  606.                 PUSH DE
  607.                 LD C,E                          ; сколько копировать
  608.                 LD DE,CPU1
  609.                 LDIR
  610.                 POP DE
  611.                 JR .L3
  612.  
  613. ; проверка для адресов чтения 0xFFxx
  614. .L5             INC A
  615.                 JR NZ,.L1
  616. ; проверка на адрес 0xFF00
  617.                 LD A,E
  618.                 AND A
  619.                 JR Z,.L1
  620. ; для загрузки в адрес выше 0xFF00 переносим только до адреса 0, остальное в игнор
  621. .L4             PUSH DE
  622.                 NEG
  623.                 LD C,A
  624.                 LD B,0
  625.                 LDIR
  626.                 POP DE
  627. .L3             INC D
  628.                 LD (OLD_HL),DE
  629.                 RET
  630.  
  631. .L1             CALL COPY_BLOCK
  632.                 LD (OLD_HL),DE
  633.                 RET
  634.  
  635. ; инфа для создания 9 сектора нового диска
  636. DSKINFO         DB 0                            ; + 0xE1 - номер первого свободного сектора
  637.                 DB 1                            ; + 0xE2 - номер первого свободного трека
  638.                 DB 0x16                         ; + 0xE3 - тип дискеты
  639.                 DB 0                            ; + 0xE4 - количество файлов на дискете
  640. SECFREE         DW 2544                         ; + 0xE5 - количество свободных секторов
  641.                 DB 0x10                         ; + 0xE7 - идентификационный код TRDOS
  642.                 DW 0                            ; + 0xE8 - 2 байта 0
  643.                 DB 9 DUP " "                    ; + 0xEA - 9 байт 0x20
  644.                 DB 0                            ; + 0xF3 - 1 байт 0
  645.                 DB 0                            ; + 0xF4 - количество удаленных файлов
  646.                 DB "RAMDISKO"                   ; + 0xF5 - имя дискеты
  647. DSK_END
  648.  
  649.                 DB LOW (-$) DUP 0
  650. MNT_SECTOR
  651.  
  652. ; адреса перехвата
  653.         JP_EMU 0x1E3A                           ; OUT      (0x3F), A
  654.         JP_EMU 0x1FDD                           ; IN    A, (0x1F)
  655.         JP_EMU 0x1FF3                           ; OUT      (0xFF), A
  656.         JP_EMU 0x2000                           ; OUT      (0x1F), A
  657.         JP_EMU 0x2076                           ; IN    A, (0x1F)
  658.         JP_EMU 0x2085                           ; OUT      (0x3F), A
  659.         JP_EMU 0x208D                           ; OUT      (0x5F), A
  660.         JP_EMU 0x2093                           ; OUT      (0x1F), A
  661.         JP_EMU 0x2099                           ; IN    A, (0x1F)
  662.         JP_EMU 0x20B1                           ; IN    A, (0xFF)
  663.         JP_EMU 0x20B8                           ; OUT      (C),    D
  664.         JP_EMU 0x2740                           ; IN    A, (0x1F)
  665.         JP_EMU 0x2748                           ; OUT      (0x7F), A
  666.         JP_EMU 0x2A53                           ; OUT      (C),    A
  667.  
  668. ; первая команда в обработчике MAGIC для возврата в пагу FE
  669. ;       JP_EMU 0x2A71                           ; OUT      (0xFF), A
  670.                 DB 0x2A71 - $ DUP 0
  671.                 OUT (EXIT_PORT),A
  672.                 JP INT_RET                      ; возвращение из обработчика INT
  673.  
  674. ;       JP_EMU 0x2A77                           ; IN    A, (0x1F)
  675.                 DB 0x2A77 - $ DUP 0
  676.                 OUT (EXIT_PORT),A
  677.                 JP RET_MNT_RW                   ; возвращение после вызова RST 8
  678.  
  679.         JP_EMU 0x2AD9                           ; OUT      (0xFF), A
  680.         JP_EMU 0x2B25                           ; IN    A, (0x5F)
  681.         JP_EMU 0x2C07                           ; IN    A, (0x5F)
  682.         JP_EMU 0x2CD8                           ; IN    A, (0x5F)
  683.         JP_EMU 0x2D75                           ; OUT      (0x5F), A
  684.         JP_EMU 0x2D80                           ; OUT      (0x1F), A
  685.         JP_EMU 0x2D87                           ; IN    A, (0x1F)
  686.         JP_EMU 0x2F0C                           ; OUT      (0xFF), A
  687.         JP_EMU 0x2F1D                           ; OUT      (0x5F), A
  688.  
  689.                 DB 0x2F24 - $ DUP 0             ; для адреса 0x2F4D
  690.                 JP ADR_0x2F4D
  691.  
  692.         JP_EMU 0x2F28                           ; OUT      (0x1F), A
  693.         JP_EMU 0x2F2F                           ; IN    A, (0x1F)
  694.         JP_EMU 0x2F3C                           ; OUT      (0xFF), A
  695.  
  696.                 DB 0x2F4D - $ DUP 0             ; OUT      (0xFF), A
  697.                 OUT (EXIT_PORT),A
  698.                 DB 0x18                         ; JR 0x2F24
  699.  
  700.         JP_EMU 0x2F50                           ; OUT      (0x7F), A
  701.  
  702.                 DB 0x2F57 - $ DUP 0             ; OUT      (0x1F), A
  703.                 OUT (EXIT_PORT),A
  704.                 JR JUMP_0x2F57
  705.  
  706.                 JR JUMP_0x2F59                  ; IN    A, (0xFF)
  707.  
  708. EXIT_0x2F59     OUT (EXIT_PORT),A
  709. JUMP_0x2F59     JP ADR_0x2F59
  710.  
  711. JUMP_0x2F57     JP ADR_0x2F57
  712.  
  713.         JP_EMU 0x2FB1                           ; OUT      (0xFF), A
  714.         JP_EMU 0x2FC3                           ; OUT      (0x1F), A
  715.  
  716.                 DB 0x32A2 - $ DUP 0
  717. ; обработчики чтения/записи портов
  718. ; запись "A" в порт 0x1F
  719. OUT_1F          LD A,(OLD_AF + 1)
  720.                 LD (WR_1F),A
  721.                 AND %11110000
  722.                 RRCA
  723.                 RRCA
  724.                 RRCA
  725.                 ADD A,LOW (.TABL_CMD)
  726.                 LD L,A
  727.                 ADC A,HIGH (.TABL_CMD)
  728.                 SUB L
  729.                 LD H,A
  730.                 LD A,(HL)
  731.                 INC HL
  732.                 LD H,(HL)
  733.                 LD L,A
  734.                 JP (HL)
  735.  
  736. .TABL_CMD       DW .CMD_00
  737.                 DW .CMD_10
  738.                 DW .CMD_20
  739.                 DW .CMD_30
  740.                 DW .CMD_40
  741.                 DW .CMD_50
  742.                 DW .CMD_60
  743.                 DW .CMD_70
  744.                 DW .CMD_80
  745.                 DW .CMD_90
  746.                 DW .CMD_A0
  747.                 DW .CMD_B0
  748.                 DW .CMD_C0
  749.                 DW .CMD_D0
  750.                 DW .CMD_E0
  751.                 DW .CMD_F0
  752.  
  753. ; 00-0F команда восстановления
  754. .CMD_00         XOR A
  755.                 LD (PORT_3F),A
  756.                 JR .INFF_BIT6
  757.  
  758. ; 10-1F команда поиска
  759. .CMD_10         LD A,(PORT_7F)
  760.                 LD (PORT_3F),A
  761.                 CALL DISK_NONE
  762.                 LD A,0x80
  763.                 JR C,.INFF_BIT6_1
  764. .INFF_BIT6      XOR A
  765. .INFF_BIT6_1    LD (RD_1F),A
  766.                 LD A,0xBF
  767.                 LD (RD_FF),A
  768.                 RET
  769.  
  770. ; 20-3F команда шаг в предыдущем направлении
  771. .CMD_20
  772. .CMD_30         LD A,(PORT_3F)
  773. .NAPRAVL        INC A
  774.                 LD (PORT_3F),A
  775.                 JR .INFF_BIT6
  776.  
  777. ; 40-5F команда шаг вперед
  778. .CMD_40
  779. .CMD_50         LD A,(PORT_3F)
  780.                 INC A
  781.                 LD (PORT_3F),A
  782.                 LD A,0x3C                       ; INC A
  783.                 LD (.NAPRAVL),A
  784.                 JR .INFF_BIT6
  785.  
  786. ; 60-7F команда шаг назад
  787. .CMD_60
  788. .CMD_70         LD A,(PORT_3F)
  789.                 DEC A
  790.                 LD (PORT_3F),A
  791.                 LD A,0x3D                       ; DEC A
  792.                 LD (.NAPRAVL),A
  793.  
  794. ; 80-9F команда чтение сектора
  795. .CMD_80
  796. .CMD_90
  797.  
  798. ; A0-BF команда запись сектора
  799. .CMD_A0
  800. .CMD_B0
  801.  
  802. ; C0-CF чтение адреса
  803. .CMD_C0         JR .INFF_BIT6
  804.  
  805. ; D0-DF принудительное прерывание
  806. .CMD_D0         LD A,0xBF
  807.                 LD (RD_FF),A
  808.                 RET
  809.  
  810. ; E0-EF чтение дорожки
  811. .CMD_E0
  812. .CMD_F0         JR .INFF_BIT6
  813.  
  814. ; запись "A" в порт 0x3F
  815. OUT_3F          LD A,(OLD_AF + 1)
  816.                 LD (PORT_3F),A
  817.                 RET
  818.  
  819. ; запись "A" в порт 0x5F
  820. OUT_5F          LD A,(OLD_AF + 1)
  821.                 LD (PORT_5F),A
  822.                 RET
  823.  
  824. ; запись "A" в порт 0x7F
  825. OUT_7F          LD A,(OLD_AF + 1)
  826.                 LD (PORT_7F),A
  827.                 RET
  828.  
  829. ; запись "A" в порт 0xFF
  830. OUT_FF          LD A,(OLD_AF + 1)
  831.                 LD (WR_FF),A
  832.                 LD D,A
  833.                 LD BC,0x00FF
  834.                 JR WR_C_D
  835.  
  836. ; запись "A" в порт (C)
  837. OUT_C_A         LD A,(OLD_AF + 1)
  838. WRCA1           LD D,A
  839.                 LD BC,(OLD_BC)                  ; если порт не TR-DOS
  840.                 LD A,C
  841. ; определение в какой порт запись      
  842.                 CP 0x1F
  843.                 JP Z,OUT_1F
  844.                 CP 0x3F
  845.                 JR Z,OUT_3F
  846.                 CP 0x5F
  847.                 JR Z,OUT_5F
  848.                 CP 0x7F
  849.                 JR Z,OUT_7F
  850.                 CP 0xFF
  851.                 JR Z,OUT_FF
  852.                 CP LOW (WIN_A0)
  853.                 JR Z,WRCA3
  854. WR_C_D          PUSH BC
  855.                 LD BC,FDD_EMU_PORT
  856.                 IN E,(C)
  857.                 XOR A
  858.                 OUT (C),A
  859.                 POP BC
  860.                 OUT (C),D
  861.                 LD BC,FDD_EMU_PORT
  862.                 OUT (C),E
  863.                 RET
  864.  
  865. ; запись в порты ATM/PENTEVO
  866. WRCA3           LD A,B
  867.                 LD HL,BB_CPU1
  868.                 CP HIGH (WIN_A1)
  869.                 JR Z,.L1
  870.                 CP HIGH (WIN_P2)
  871.                 JR Z,.L1
  872.                 LD HL,BB_CPU2
  873.                 CP HIGH (WIN_A2)
  874.                 JR Z,.L1
  875.                 CP HIGH (WIN_P2)
  876.                 JR NZ,WR_C_D
  877. .L1             LD E,B
  878.                 PUSH DE
  879.                 PUSH HL
  880.                 CALL READ_CPU12
  881.                 POP HL
  882.                 POP DE
  883.                 LD (HL),D
  884.                 INC HL
  885.                 LD (HL),E
  886.                 JP WRITE_CPU12
  887.  
  888. ; запись "D" в порт (C)
  889. OUT_C_D         LD A,(OLD_DE + 1)
  890.                 JR WRCA1
  891.  
  892. ; передача байта, команда OUTI
  893. OUT_OUTI        LD HL,(BUFF_SECT)
  894.                 EXX
  895.                 LD A,(HL)
  896.                 INC HL
  897.                 EXX
  898.                 LD (HL),A
  899.                 INC HL
  900.                 LD (BUFF_SECT),HL
  901.                 RET
  902.  
  903. ; чтение порта 0x1F
  904. IN_1F           LD A,(WR_1F)
  905.                 AND %11110000
  906.                 CP 0x10
  907.                 JR C,.L1                        ; 00-0F команды восстановления
  908.                 CP 0x20
  909.                 JR C,.L3                        ; 10-1F команды поиска
  910.                 CP 0x80
  911.                 JR C,.L5                        ; 20-7F команды шагания головки
  912.                 CP 0xC0
  913.                 JR C,.L8                        ; 80-BF команды чтения/записи
  914.                 CP 0xD0
  915.                 JR Z,.L1                        ; D0-DF команды принудительного прерывания
  916.                 XOR A
  917.                 JR .L2
  918.  
  919. ; проверка выхода за 80 дорожку
  920. .L8             LD A,(PORT_3F)
  921.                 CP 80
  922.                 LD A,0
  923.                 JR C,.L2
  924.                 LD A,%00010000                  ; при уходе за 80 дорожку выдача ошибки "массив не найден"
  925.                 JR .L2
  926.  
  927. .L5             LD A,(PORT_3F)
  928.                 AND A
  929.                 JR NZ,.L1
  930.                 LD A,%00100100
  931.                 JR .L6
  932.  
  933. .L3             LD A,(.INDEX)
  934.                 XOR %00000100
  935.                 JR .L4
  936.  
  937. .L1             LD A,%00100100
  938. .INDEX          EQU $-1
  939. .L4             XOR %00000010
  940. .L6             LD (.INDEX),A
  941. .L2             LD (RD_1F),A
  942.                 LD (OLD_AF + 1),A
  943.                 RET
  944.  
  945. ; чтение порта 0x3F
  946. IN_3F           LD A,(PORT_3F)
  947.                 LD (OLD_AF + 1),A
  948.                 RET
  949.  
  950. ; чтение порта 0x5F
  951. IN_5F           LD A,(PORT_5F)
  952.                 LD (OLD_AF + 1),A
  953.                 RET
  954.  
  955. ; чтение порта 0x7F
  956. IN_7F           LD A,(PORT_7F)
  957.                 LD (OLD_AF + 1),A
  958.                 RET
  959.  
  960. ; чтение порта 0xFF
  961. IN_FF           LD A,(RD_FF)
  962.                 LD (OLD_AF + 1),A
  963.                 RET
  964.  
  965. ; чтение в "H" из (С)
  966. IN_H_C          LD A,(OLD_BC)
  967. ; определение из какого порта чтение
  968.                 CP 0x1F
  969.                 JR NZ,.L2
  970.                 LD A,(RD_1F)
  971.                 LD (OLD_HL + 1),A
  972.                 RET
  973.  
  974. .L2             CP 0x3F
  975.                 JR NZ,.L3
  976.                 LD A,(PORT_3F)
  977.                 LD (OLD_HL + 1),A
  978.                 RET
  979.  
  980. .L3             CP 0x5F
  981.                 JR NZ,.L4
  982.                 LD A,(PORT_5F)
  983.                 LD (OLD_HL + 1),A
  984.                 RET
  985.  
  986. .L4             CP 0x7F
  987.                 JR NZ,.L5
  988.                 LD A,(PORT_7F)
  989.                 LD (OLD_HL+1),A
  990.                 RET
  991.  
  992. .L5             CP 0xFF
  993.                 JR NZ,.L6
  994.                 LD A,(RD_FF)
  995.                 LD (OLD_HL + 1),A
  996.                 RET
  997.  
  998. .L6             LD BC,(OLD_BC)
  999.                 IN A,(C)
  1000.                 LD (OLD_HL + 1),A
  1001.                 RET
  1002.  
  1003. ; чтение INI
  1004. IN_INI          LD HL,(OLD_HL)
  1005.                 LD A,H
  1006.                 CP 0x40
  1007.                 JR C,.L1
  1008.                 DEC HL
  1009.                 LD A,(RD_1F)
  1010.                 LD (HL),A
  1011. ; временно, для анрыла
  1012. ;               LD A,0xD3
  1013. ;               LD (0x3FD7),A
  1014. ; временно, для анрыла
  1015. .L1             LD HL,0x2A53
  1016.                 LD (ADR_EXIT),HL
  1017.                 JP OUT_1F.INFF_BIT6
  1018.  
  1019. WAIT_READ       LD A,(WR_1F)
  1020.                 AND 0xF0
  1021.                 CP 0x80
  1022.                 JP C,OUT_1F.INFF_BIT6
  1023.                 CP 0xC0
  1024.                 JR NC,READ_SECTOR.L1
  1025.                 CALL READ_CPU12                 ; сохранение текущей конфигурации окон проецирования 1,2
  1026.                 CALL FIND_SECTOR                ; проверяем наличие сектора
  1027.                 PUSH AF
  1028.                 CALL WRITE_CPU12                ; восстановление конфигурации окон проецирования 1,2
  1029.                 POP AF
  1030.                 JR NC,READ_SECTOR_1
  1031. ; сектора нет, не дождетесь
  1032.                 LD A,0x3C
  1033.                 JP OUT_1F.INFF_BIT6_1
  1034.  
  1035. ; чтение сектора или портов
  1036. READ_SECTOR     LD A,(WR_1F)
  1037.                 AND 0xF0
  1038.                 CP 0x80
  1039.                 JP C,OUT_1F.INFF_BIT6
  1040.                 CP 0xC0
  1041.                 JR C,READ_SECTOR_1
  1042. .L1             CALL READ_CPU12                 ; чтение текущей конфы
  1043.                 LD BC,WIN_A1
  1044.                 LD A,0x40
  1045.                 OUT (C),A
  1046.                 LD B,HIGH (WIN_P1)
  1047.                 LD A,RAM_RAMDISK
  1048.                 OUT (C),A                       ; страница заголовков рамдиска
  1049.                 LD A,(PORT_3F)                  ; взяли номер трека
  1050.                 ADD A,A                         ; сторон 2
  1051.                 LD C,A
  1052.                 LD A,(WR_FF)
  1053.                 AND 0x10                        ; проверка какая сторона диска
  1054.                 JR NZ,.L2
  1055.                 INC C                           ; для стороны 1
  1056. .L2             LD B,HIGH (CPU1) + 2            ; адрес начала инфы о секторах на дорожке
  1057.                 LD A,0                          ; текущий номер сектора
  1058. .CURR_SEC       EQU $-1
  1059.                 INC A
  1060.                 AND %00001111
  1061.                 LD (.CURR_SEC),A
  1062.                 ADD A,A
  1063.                 ADD A,HIGH (CPU1) + 2
  1064.                 LD B,A
  1065.                 LD A,(PORT_3F)                  ; номер дорожки
  1066.                 LD C,A
  1067.                 LD A,(BC)                       ; проичтали номер сектора
  1068.                 PUSH AF
  1069.                 CALL WRITE_CPU12                ; восстановление конфы
  1070.                 LD A,(PORT_3F)
  1071.                 LD HL,(OLD_HL)
  1072.                 LD (HL),A                       ; номер дорожки
  1073.                 INC HL
  1074.                 LD (HL),0                       ; номер стороны
  1075.                 INC HL
  1076.                 POP AF
  1077.                 LD (HL),A                       ; номер сектора
  1078.                 INC HL
  1079.                 LD (HL),0                       ; размер сектора
  1080.                 INC HL
  1081.                 LD (HL),0                       ; байт CRC
  1082.                 INC HL
  1083.                 LD (HL),0                       ; байт CRC
  1084.                 INC HL
  1085.                 LD (OLD_HL),HL
  1086.                 LD HL,OLD_BC + 1
  1087.                 LD A,(HL)
  1088.                 SUB 6                           ; REG B - 6
  1089.                 LD (HL),A
  1090.                 LD HL,0x2A53
  1091.                 LD (ADR_EXIT),HL
  1092.                 JP OUT_1F.INFF_BIT6
  1093.  
  1094. ; чтение сектора
  1095. READ_SECTOR_1   XOR A
  1096.                 JR WRITE_SECTOR.L1
  1097.  
  1098. ; запись сектора
  1099. WRITE_SECTOR    LD A,0xFF
  1100. .L1             LD (RDWR_MODE),A
  1101.                 LD A,1
  1102.                 LD (FLAG_RW_BREAK),A
  1103.                 LD HL,(OLD_IF)
  1104.                 PUSH HL
  1105.                 POP AF
  1106.                 JP PO,.DI_MODE                  ; прерывания разрешены?
  1107.                 CP 0x3F
  1108.                 JR Z,.DI_MODE
  1109.                 HALT                            ; разрешены, ждем обработчик прерывания
  1110. .DI_MODE        CALL READ_CPU12                 ; сохранение текущей конфигурации окон проецирования 1,2
  1111.                 CALL W_WR_RD_SECT
  1112.                 XOR A
  1113.                 LD (FLAG_RW_BREAK),A
  1114.                 LD HL,0x8090
  1115.                 LD (OLD_AF),HL                  ; эмуляция флага успешного чтения/записи сектора
  1116.                 LD HL,0x2A53
  1117.                 LD (ADR_EXIT),HL
  1118.                 JP WRITE_CPU12                  ; восстановление конфигурации окон проецирования 1,2
  1119.  
  1120. ; поиск сектора в таблице
  1121. FIND_SECTOR     LD BC,WIN_A1
  1122.                 LD A,0x40
  1123.                 OUT (C),A
  1124.                 LD B,HIGH (WIN_P1)
  1125.                 LD A,RAM_RAMDISK
  1126.                 OUT (C),A                       ; страница заголовков рамдиска
  1127.                 LD A,(PORT_3F)                  ; взяли номер трека
  1128.                 ADD A,A                         ; сторон 2
  1129.                 LD C,A
  1130.                 LD A,(WR_FF)
  1131.                 AND 0x10                        ; проверка какая сторона диска
  1132.                 JR NZ,.L2
  1133.                 INC C                           ; для стороны 1
  1134. .L2             LD B,HIGH (CPU1) + 2            ; адрес начала инфы о секторах на дорожке
  1135.                 LD HL,(PORT_5F)                 ; взяли номер сектора
  1136.                 LD H,0
  1137. .L1             LD A,(BC)
  1138.                 LD D,A                          ; взяли номер сектора
  1139.                 INC B
  1140.                 LD A,(BC)
  1141.                 LD E,A                          ; взяли размер сектора
  1142.                 INC B
  1143. ;               LD A,D
  1144.                 AND A
  1145.                 SCF
  1146.                 RET Z                           ; ошибка, сектор не найден
  1147.                 LD A,L
  1148.                 CP D
  1149.                 RET Z                           ; сектор найден
  1150.                 LD A,E
  1151.                 ADD A,H
  1152.                 LD H,A
  1153.                 JR .L1
  1154.  
  1155. ; чтение или запись сектора рамдиска
  1156. W_WR_RD_SECT    LD A,(WR_FF)
  1157.                 AND 3
  1158.                 INC A
  1159.                 LD B,A
  1160.                 LD A,%10000000
  1161. .L1             RLCA
  1162.                 DJNZ .L1
  1163.                 LD B,A
  1164.                 LD A,(COPY_VIRT_BITS)
  1165.                 AND B
  1166.                 JP NZ,MOUNT_RW                  ; работа с примонтированным образом
  1167.                 CALL FIND_SECTOR
  1168.                 JR NC,.L2
  1169. ; сектор не найден, на выход
  1170.                 LD A,0x10
  1171.                 JP IN_1F.L2
  1172.  
  1173. ; сектор найден, читаем/пишем
  1174. .L2             LD A,E
  1175.                 RRCA
  1176.                 LD (SECTOR_SIZE),A              ; размер найденного сектора
  1177.                 LD L,0
  1178.                 LD E,L
  1179.                 SRL H
  1180.                 RR L                            ; HL = смещение в блоках до найденного сектора
  1181.                 LD B,HIGH (CPU1)
  1182.                 LD A,(BC)
  1183.                 LD D,A
  1184.                 ADD HL,DE                       ; HL = смещение от начала страницы в блоках
  1185.                 INC B
  1186.                 LD A,(BC)
  1187.                 LD C,A                          ; смещение в страницах от начала рамдиска
  1188.                 LD A,H
  1189.                 CP HIGH (CPU1)
  1190.                 JR C,.L5
  1191.                 SUB 0x40
  1192.                 LD H,A
  1193.                 INC C
  1194. ; HL = смещение в странице до начала сектора
  1195. .L5             LD A,C                          ; смещение до номера страницы, где указанный сектор начинается
  1196.                 ADD A,RAM_DATARAMD              ; прибавили номер начала рамдиск и +1. в 0 странице рамдиска описатели секторов
  1197.                 LD (RDWR_PAGE),A                ; сохранили номер вычисленной страницы
  1198.                 LD DE,(OLD_HL)                  ; адрес куда/откуда копировать
  1199.                 LD BC,(BB_CPU1)
  1200.                 LD A,C
  1201.                 LD C,LOW (WIN_A0)
  1202.                 OUT (C),A                       ; вернули стандартную 5 страницу
  1203. .S9             LD A,D                          ; проверка границы откуда/куда копировать
  1204.                 CP HIGH (CPU2)
  1205.                 PUSH DE
  1206.                 LD DE,CPU1 + HIGH (WIN_P1)
  1207.                 LD BC,WIN_A1                    ; если верхние 32кб озу, то нужно включить в 1 окне проецирования
  1208.                 JR NC,.S1
  1209.                 LD DE,CPU2 + HIGH (WIN_P2)
  1210.                 LD B,HIGH (WIN_A2)              ; если нижние 32кб озу, то нужно включить во 2 окне проецирования
  1211. .S1             LD A,0x40
  1212.                 OUT (C),A
  1213.                 LD B,E
  1214.                 LD A,(RDWR_PAGE)                ; номер вычисленной страницы озу
  1215.                 OUT (C),A                       ; включили вычисленную страницу
  1216.                 LD B,D                          ; старший байт адреса начала включенной страницы
  1217.                 POP DE
  1218.                 LD A,B
  1219.                 ADD A,H
  1220.                 LD H,A
  1221.                 LD A,(RDWR_MODE)
  1222.                 AND A
  1223.                 JR NZ,.I1
  1224.                 LD A,D
  1225.                 INC A
  1226.                 JR NZ,.I1
  1227.                 LD A,E
  1228.                 AND A
  1229.                 JR Z,.I1
  1230.                 NEG
  1231.                 LD C,A
  1232.                 LD B,0
  1233.                 LDIR
  1234.                 NEG
  1235.                 LD C,A
  1236. .I2             EX DE,HL
  1237.                 ADD HL,BC
  1238.                 EX DE,HL
  1239.                 ADD HL,BC
  1240.                 LD A,(SECTOR_SIZE)
  1241.                 JP .S8_
  1242.  
  1243. .I1             LD A,D
  1244.                 CP HIGH (CPU1)
  1245.                 JR NC,.I3
  1246.                 LD A,(SECTOR_SIZE)
  1247.                 AND A
  1248.                 LD BC,0x80
  1249.                 JR Z,.I2
  1250.                 LD BC,0x100
  1251.                 JR .I2
  1252.  
  1253. .I3             CP HIGH (CPU2)                  ; проверка перехода границы страниц
  1254.                 JP NC,.S3                       ; если выше то сразу копируем
  1255.                 CP HIGH (CPU2) - 1
  1256.                 JP C,.S3                        ; если ниже так же сразу копируем
  1257.                 LD A,E
  1258.                 AND A                           ; если сектор полностью укладывется до границы, то сразу копируем
  1259.                 JR Z,.S3                        ; иначе принудительно копируем в два приема
  1260.                 LD A,(RDWR_MODE)                ; чтение или запись?
  1261.                 AND A
  1262.                 LD A,E                          ; младший байт адрес в блоке
  1263.                 JR Z,.S4
  1264.                 EX DE,HL                        ; для записи меняем направление
  1265. .S4             NEG
  1266.                 LD C,A                          ; копируем остаток до конца блока
  1267.                 LD B,0
  1268.                 LDIR
  1269.                 NEG
  1270.                 PUSH AF                         ; спрятали сколько осталось копировать из начала следующего блока
  1271.                 LD BC,(BB_CPU2)
  1272.                 LD A,C
  1273.                 LD C,LOW (WIN_A0)
  1274.                 OUT (C),A
  1275.                 LD B,HIGH (WIN_A1)
  1276.                 LD A,0x40
  1277.                 OUT (C),A
  1278.                 LD B,HIGH (WIN_P1)
  1279.                 LD A,(RDWR_PAGE)
  1280.                 OUT (C),A                       ; вычисленную страницу включаем в 1 окне проецирования
  1281.                 LD A,(RDWR_MODE)                ; чтение или запись
  1282.                 AND A
  1283.                 JR Z,.S5
  1284.                 LD A,D                          ; для записи
  1285.                 SUB 0x40                        ; изменили адрес куда копировать на другое окно проецирования
  1286.                 LD D,A
  1287.                 JR .S6
  1288.  
  1289. .S5             LD A,H                          ; для чтения
  1290.                 SUB 0x40                        ; изменили адрес куда копировать на другое окно проецирования
  1291.                 LD H,A
  1292. .S6             POP AF
  1293.                 LD C,A                          ; сколько осталось скопировать байт
  1294.                 LD B,0
  1295.                 LDIR
  1296.                 LD A,(SECTOR_SIZE)
  1297.                 JR .S8_
  1298.  
  1299. .S3             LD A,(RDWR_MODE)                ; чтение или запись
  1300.                 AND A
  1301.                 JR Z,.S7
  1302.                 EX DE,HL                        ; для записи меняем направление
  1303. .S7             LD A,(SECTOR_SIZE)
  1304.                 AND A
  1305.                 JR NZ,.S8
  1306.                 CALL COPYHBLOCK                 ; для сектора размером 128 байт копируем половину и выходим
  1307. .ECOPY_BLOCK    LD A,(RDWR_MODE)
  1308.                 AND A
  1309.                 JR Z,.ECOPY_BLOCK1
  1310.                 EX DE,HL
  1311. .ECOPY_BLOCK1   LD (OLD_HL),DE
  1312.                 RET
  1313.  
  1314. .S8             CALL COPY_BLOCK                 ; для сектора 256 байт копируем весь и выходим
  1315. .S8_            DEC A
  1316.                 JR Z,.ECOPY_BLOCK
  1317.                 LD (SECTOR_SIZE),A
  1318.                 LD A,(RDWR_MODE)
  1319.                 AND A
  1320.                 JR Z,.S0
  1321.                 EX DE,HL
  1322. .S0             LD A,0x3F
  1323.                 AND H
  1324.                 LD H,A
  1325.                 JP .S9
  1326.  
  1327. COPY_BLOCK
  1328.         REPT 128
  1329.                 LDI
  1330.         ENDM
  1331. COPYHBLOCK
  1332.         REPT 128
  1333.                 LDI
  1334.         ENDM
  1335.                 RET
  1336.  
  1337. ; проверка наличия маркера рамдиска
  1338. CMP_RAM_DISK    CALL READ_CPU12
  1339.                 LD BC,WIN_P1
  1340.                 LD A,RAM_RAMDISK
  1341.                 OUT (C),A
  1342.                 LD HL,CPU1 + 0x3FFF
  1343.                 LD D,(HL)
  1344.                 DEC H
  1345.                 LD E,(HL)                       ; взяли байты для проверки маркера
  1346.                 CALL WRITE_CPU12
  1347.                 LD HL,"RD"
  1348.                 AND A
  1349.                 SBC HL,DE
  1350.                 RET Z                           ; если маркер на месте, то рамдиска не создаем
  1351. ; создание чистого рамдиска
  1352. CREATE_TRDTABL  LD BC,WIN_P1
  1353.                 LD A,RAM_RAMDISK                ; нужна страница начала рамдиска, где будет таблица описателей
  1354.                 OUT (C),A
  1355.                 LD HL,CPU1
  1356.                 PUSH HL
  1357.                 LD DE,CPU1 + 1
  1358.                 LD BC,0x3FFF
  1359.                 LD (HL),L
  1360.                 LDIR                            ; очистили страницу
  1361.                 POP DE                          ; адрес начала страницы
  1362.                 LD HL,0                         ; смещение в блоках и страницах
  1363.                 LD A,0xA0
  1364. .L1             PUSH AF
  1365.                 LD BC,0x1000                    ; счетчик номеров секторов и их номера
  1366.                 LD A,L
  1367.                 RRCA
  1368.                 RRCA
  1369.                 LD (DE),A                       ; смещение в блоках дорожки в странице
  1370.                 INC D
  1371.                 LD A,H
  1372.                 LD (DE),A                       ; смещение в страницах до дорожки
  1373.                 INC D
  1374. .L2             INC C
  1375.                 LD A,C
  1376.                 LD (DE),A                       ; номер сектора
  1377.                 INC D
  1378.                 LD A,2
  1379.                 LD (DE),A                       ; размер сектора
  1380.                 INC D
  1381.                 DJNZ .L2                        ; вносим в таблицу все номера секторов с размерами
  1382.                 LD D,HIGH (CPU1)                ; вернули указатель в начало
  1383.                 INC E                           ; для следующей дорожки
  1384.                 LD BC,0x40
  1385.                 ADD HL,BC                       ; переход к следующей дорожке
  1386.                 POP AF
  1387.                 DEC A
  1388.                 JR NZ,.L1                       ; повторяем для всех дорожек
  1389.                 LD HL,CPU1 + 0x3FFF
  1390.                 LD (HL),"R"                     ; вносим маркер рамдиска
  1391.                 DEC H
  1392.                 LD (HL),"D"
  1393.                 LD BC,WIN_P1
  1394.                 LD A,RAM_DATARAMD
  1395.                 OUT (C),A
  1396.                 LD HL,CPU1
  1397.                 LD DE,CPU1 + 1
  1398.                 LD BC,0x0FFF
  1399.                 LD (HL),L
  1400.                 LDIR
  1401.                 LD HL,DSKINFO
  1402.                 LD DE,CPU1 + 0x08E1
  1403.                 LD BC,DSK_END - DSKINFO
  1404.                 LDIR
  1405. ; восстановление конфигурации окон проецирования 1,2
  1406. WRITE_CPU12     LD BC,(BB_CPU1)
  1407.                 LD A,C
  1408.                 LD C,LOW (WIN_A0)
  1409.                 OUT (C),A
  1410.                 LD BC,(BB_CPU2)
  1411.                 LD A,C
  1412.                 LD C,LOW (WIN_A0)
  1413.                 OUT (C),A
  1414.                 RET
  1415.  
  1416. ; чтение текущего конфига страниц проецирования 1,2
  1417. READ_TMP_CPU12  LD HL,(BB_CPU1)
  1418.                 PUSH HL
  1419.                 LD HL,(BB_CPU2)
  1420.                 PUSH HL
  1421.                 CALL READ_CPU12
  1422.                 LD HL,(BB_CPU1)
  1423.                 LD (TMP_BB_CPU1),HL
  1424.                 LD HL,(BB_CPU2)
  1425.                 LD (TMP_BB_CPU2),HL
  1426.                 POP HL
  1427.                 LD (BB_CPU2),HL
  1428.                 POP HL
  1429.                 LD (BB_CPU1),HL
  1430.                 JR WRITE_CPU12
  1431.  
  1432. ; восстановление текущей конфигурации страниц проецирования 1,2
  1433. WRITE_TMP_CPU12 LD BC,0
  1434. TMP_BB_CPU1     EQU $-2
  1435.                 LD A,C
  1436.                 LD C,LOW (WIN_A0)
  1437.                 OUT (C),A
  1438.                 LD BC,0
  1439. TMP_BB_CPU2     EQU $-2
  1440.                 LD A,C
  1441.                 LD C,LOW (WIN_A0)
  1442.                 OUT (C),A
  1443.                 RET
  1444.  
  1445. ; чтение конфигурации окон проецирования 1,2
  1446. READ_CPU12      LD BC,RD_RAMNROM
  1447.                 IN L,(C)                        ; биты RAM & ROM
  1448.                 INC B
  1449.                 IN H,(C)                        ; биты DOS & 7FFD
  1450.                 ADD HL,HL
  1451.                 LD B,HIGH (RD_1WINA1)
  1452.                 IN A,(C)
  1453.                 CP 0xC0
  1454.                 JR NC,.L1
  1455.                 LD E,A
  1456.                 LD D,HIGH (WIN_P1)
  1457.                 JR .L2
  1458.  
  1459. .L1             RLCA
  1460.                 RLCA
  1461.                 SLA L
  1462.                 RRA
  1463.                 SLA H
  1464.                 RRA
  1465.                 LD E,A
  1466.                 LD D,HIGH (WIN_A1)
  1467. .L2             LD (BB_CPU1),DE
  1468.                 INC B
  1469.                 IN A,(C)
  1470.                 CP 0xC0
  1471.                 JR NC,.L3
  1472.                 LD E,A
  1473.                 LD D,HIGH (WIN_P2)
  1474.                 JR .L4
  1475.  
  1476. .L3             RLCA
  1477.                 RLCA
  1478.                 SLA L
  1479.                 RRA
  1480.                 SLA H
  1481.                 RRA
  1482.                 LD E,A
  1483.                 LD D,HIGH (WIN_A2)
  1484. .L4             LD (BB_CPU2),DE
  1485.                 RET
  1486.  
  1487. ; проверка наличия виртуального диска
  1488. DISK_NONE       PUSH HL
  1489.                 PUSH BC
  1490.                 CALL READ_CPU12
  1491.                 LD BC,WIN_A1
  1492.                 LD A,0x40
  1493.                 OUT (C),A
  1494.                 LD B,HIGH (WIN_P1)
  1495.                 LD A,RAM_RAMDISK
  1496.                 OUT (C),A
  1497.                 LD HL,CPU1 + 0x3FFF
  1498.                 LD A,(HL)
  1499.                 DEC H
  1500.                 CP "R"
  1501.                 SCF
  1502.                 JR NZ,.L1
  1503.                 LD A,(HL)
  1504.                 CP "D"
  1505.                 SCF
  1506.                 JR NZ,.L1
  1507.                 XOR A
  1508. .L1             PUSH AF
  1509.                 CALL WRITE_CPU12
  1510.                 POP AF
  1511.                 POP BC
  1512.                 POP HL
  1513.                 RET
  1514.  
  1515. ; на входе: H-адрес ячейки
  1516. ;           L-прочитанное значение
  1517. READCMOS        PUSH BC
  1518.                 LD BC,CMOSD_SET_ADR
  1519.                 OUT (C),H
  1520.                 LD B,HIGH (CMOSD_RD_WR)
  1521.                 IN L,(C)
  1522.                 POP BC
  1523.                 LD A,L
  1524.                 AND A
  1525.                 RET
  1526.  
  1527.         JP_EMU 0x3C30                           ; IN    A, (0x1F)
  1528.  
  1529.                 DB 0x3D2F - $ DUP 0
  1530.                 NOP
  1531.                 RET
  1532.  
  1533.         JP_EMU 0x3D4D                           ; OUT      (0xFF), A
  1534.         JP_EMU 0x3D9A                           ; OUT      (0x1F), A
  1535.         JP_EMU 0x3DA6                           ; IN    A, (0xFF)
  1536.         JP_EMU 0x3DB5                           ; IN    A, (0x1F)
  1537.         JP_EMU 0x3DBA                           ; IN    A, (0x1F)
  1538.         JP_EMU 0x3DD5                           ; OUT      (0xFF), A
  1539.         JP_EMU 0x3E30                           ; IN    A, (0x1F)
  1540.         JP_EMU 0x3E3A                           ; IN    A, (0x1F)
  1541.         JP_EMU 0x3E44                           ; OUT      (0x7F), A
  1542.  
  1543.                 DB 0x3E49 - $ DUP 0
  1544.                 JP ADR_0x3E4C                   ; для адреса 0x3E4C
  1545.  
  1546. ;               JP_EMU 0x3E4C                   ; OUT      (0x7F), A
  1547.                 DB 0x3E4C - $ DUP 0
  1548.                 OUT (EXIT_PORT),A
  1549.                 JR 0x3E49
  1550.  
  1551.         JP_EMU 0x3E50                           ; IN    A, (0x3F)
  1552.         JP_EMU 0x3E78                           ; IN    A, (0x3F)
  1553.         JP_EMU 0x3E7E                           ; OUT      (0x3F), A
  1554.         JP_EMU 0x3E87                           ; IN    A, (0x3F)
  1555.         JP_EMU 0x3E95                           ; OUT      (0x3F), A
  1556.         JP_EMU 0x3EB5                           ; IN    A, (0x1F)
  1557.         JP_EMU 0x3EBC                           ; IN    A, (0x3F)
  1558.         JP_EMU 0x3EC9                           ; OUT      (0x1F), A
  1559.         JP_EMU 0x3ECE                           ; IN    A, (0xFF)
  1560.         JP_EMU 0x3EDF                           ; OUT      (0x1F), A
  1561.  
  1562.                 DB 0x3EF3 - $ DUP 0             ; IN    H, (C)
  1563.                 OUT (EXIT_PORT),A
  1564.                 JR JUMP_0x3EF3
  1565.  
  1566.                 JR JUMP_0x3EF5                  ; IN    A, (0xFF)
  1567.  
  1568. EXIT_0x3EF5     OUT (EXIT_PORT),A
  1569. JUMP_0x3EF5     JP ADR_0x3EF5
  1570.  
  1571. ;       JP_EMU 0x3EF5                           ; IN    A, (0xFF)
  1572.         JP_EMU 0x3EFE                           ; IN    A, (0x7F)
  1573.  
  1574. JUMP_0x3EF3     JP ADR_0x3EF3
  1575.  
  1576.                 JP_EMU 0x3F1B                   ; OUT      (0x5F), A
  1577.                 JP_EMU 0x3F25                   ; OUT      (0x1F), A
  1578.                 JP_EMU 0x3F33                   ; IN    A, (0x1F)
  1579.  
  1580.                 DB 0x3F40 - $ DUP 0             ; для адреса 0x3EF3
  1581.                 JP ADR_0x3EF3
  1582.  
  1583.         JP_EMU 0x3F4D                           ; OUT      (0x1F), A
  1584.         JP_EMU 0x3F55                           ; IN    A, (0x3F)
  1585.         JP_EMU 0x3F5A                           ; IN    A, (0x5F)
  1586.         JP_EMU 0x3F69                           ; IN    A, (0x3F)
  1587.         JP_EMU 0x3F72                           ; IN    A, (0x5F)
  1588.  
  1589.         JP_EMU 0x3FBC                           ; IN    A, (0xFF)       ;запись сектора
  1590.  
  1591.                 DB 0x3FC7 - $ DUP 0
  1592. JUMP_0x3FF0     JP ADR_0x3FF0
  1593.  
  1594.         JP_EMU 0x3FCA                           ; IN    A, (0xFF)       ;запись сектора
  1595.         JP_EMU 0x3FD1                           ; OUTI                  ;запись сектора
  1596.  
  1597.         JP_EMU 0x3FD7                           ; IN    A, (0xFF)       ;чтение сектора
  1598.  
  1599. JUMP_0x3FEC     JP ADR_0x3FEC
  1600. JUMP_0x3FF3     JP ADR_0x3FF3
  1601.  
  1602.         JP_EMU 0x3FE5                           ; IN    A, (0xFF)       ;чтение сектора
  1603.  
  1604. ;       JP_EMU 0x3FEC                           ; INI                   ;чтение сектора
  1605.                 DB 0x3FEC - $ DUP 0
  1606.                 OUT (EXIT_PORT),A
  1607.                 JR JUMP_0x3FEC
  1608.  
  1609. ;               DB 0x3FF0 - $ DUP 0             ; OUT      (C), A
  1610.                 OUT (EXIT_PORT),A
  1611.                 DB 0x18                         ; JR 0x3FC7
  1612.  
  1613. ;               DB 0x3FF5 - $ DUP 0             ; IN    A, (C)
  1614.                 OUT (EXIT_PORT),A
  1615.                 JP JUMP_0x3FF3
  1616.  
  1617.                 DB 0x3FF8 - $ DUP 0
  1618.                 DB "EVOSFE"
  1619.                 DW DATA_VERS
  1620.