Subversion Repositories pentevo

Rev

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

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