Subversion Repositories NedoOS

Rev

Rev 1025 | Rev 1031 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1.         DEVICE ZXSPECTRUM1024
  2.         include "../_sdk/sys_h.asm"
  3.  
  4. ;emul=в 0000
  5. ;основной набор регистров=в альтернативном наборе
  6. ;PC=в DE
  7. ;текущий индексный=в IX
  8. ;не текущий индексный=в _IZ
  9. ;SP=в _SP (todo в (SP)? но там сейчас jpiyer для выхода из DOSER. сделать в DOSER 2-байтный патч?)
  10.  
  11. STACK=0x4000
  12.  
  13. stats=0 ;статистика по опкодам
  14.  
  15. margins=1 ;1=хранить в de уже пересчитанный PC
  16. MEM48C0=1 ;8000,c000 - всегда замапленные страницы ;4000 - страница ПЗУ или текущая 4000 (каждый раз включать)
  17.  
  18. extpg5=0 ;1=стр5 лежит в pg5,иначе в #4000(без перехвата экрана)
  19.         ;экран надо строить редко, в scr2
  20.  
  21. skipIM1=1 ;1=вместо трассировки #38 вызываем ее (если IY=23610)
  22.  
  23.         MACRO OUTPG
  24.         SETPGC000
  25.         ENDM
  26.  
  27.        if margins
  28.         MACRO OUTPGCOM
  29.         SETPG4000
  30.         ENDM
  31.        endif
  32.  
  33.         MACRO OUTPG4000
  34.         SETPG4000
  35.         ENDM
  36.  
  37.         MACRO _Loop_
  38.         JP (IY) ;EMULOOP
  39.         ENDM
  40.  
  41. ;если вместо стр.команд включили др.стр.
  42.         MACRO _LoopC
  43.         OUTcom
  44.         JP (IY)
  45.         ENDM
  46.  
  47. ;если резко сменился PC (полный DE)
  48.         MACRO _LoopJP
  49.         CALCiypgcom
  50.         jp DOSER
  51.         ENDM
  52.         MACRO _LoopJP_NODOS
  53.         CALCiypgcom
  54.         JP (IY)
  55.         ENDM
  56.  
  57. ;если эмулятор щёлкал страницу и резко сменился PC (полный DE)
  58.         MACRO _LoopC_JP
  59.         CALCiypgcom
  60.         jp DOSER
  61.         ENDM
  62.         MACRO _LoopC_JP_NODOS
  63.         CALCiypgcom
  64.         JP (IY)
  65.         ENDM
  66.  
  67. ;если IN/OUT (могла измениться конфигурация памяти - но там внутри уже CALCpgcom)
  68.         MACRO _LoopSWI
  69.         ;CALCpgcom
  70.         JP (IY)
  71.         ENDM
  72.  
  73. ;BC,DE,HL,AF -> BC
  74. ;rp=A&#30
  75.         MACRO rptoBC
  76.         AND #30
  77.         OR #C5 ;PUSH rp
  78.         LD ($+5),A
  79.         EXX
  80.         EXA
  81.         PUSH BC ;DE;HL;AF
  82.         EXX
  83.         EXA
  84.         POP BC
  85.         ENDM
  86.  
  87. ;BC,DE,HL,AF <- BC
  88. ;rp=A&#30
  89.         MACRO BCtorp
  90.         AND #30
  91.         OR #C1 ;POP rp
  92.         PUSH BC
  93.         LD ($+5),A
  94.         EXX
  95.         EXA
  96.         POP BC ;DE;HL;AF
  97.         EXX
  98.         EXA
  99.         ENDM
  100.  
  101. ;берем смещение d
  102. ;результат HL=IX+d
  103.         MACRO getdIXtoHL
  104.         get
  105.         next
  106.         LD L,A
  107.         RLA
  108.         SBC A,A
  109.         LD H,A
  110.         PUSH IX
  111.         POP BC
  112.         ADD HL,BC
  113.         ENDM
  114.  
  115.        if margins
  116.         include "mem_marg.asm"
  117.        else
  118.        if MEM48C0
  119.         include "mem_48c0.asm"
  120.        else
  121.         include "mem_c000.asm"
  122.        endif
  123.        endif
  124.  
  125.         org PROGSTART
  126. begin
  127.         ld sp,STACK
  128.         OS_HIDEFROMPARENT
  129.         ld e,3+0x80 ;keep
  130.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  131.         ;ld e,0 ;color byte
  132.         ;OS_CLS
  133.  
  134.         OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  135.        push hl
  136.         ld hl,temulpgs
  137.         ld a,d
  138.         ld (deadpg),a
  139.         ld (hl),d
  140.         ld d,h
  141.         ld e,l
  142.         inc de
  143.         ld bc,64-1
  144.         ldir
  145.  
  146.         ld a,(user_scr0_high) ;ok
  147.         ld (curpg5),a
  148.         ld (temulpgs+5),a
  149.         SETPG4000
  150.         ld a,(user_scr1_high) ;ok
  151.         ld (temulpgs+7),a
  152.  
  153.         ;OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  154.        pop hl
  155.         ld a,h
  156.         ld (curpg2),a
  157.         ld (temulpgs+2),a
  158.         ld a,l
  159.         ld (temulpgs+0),a
  160.  
  161.         ld de,path
  162.         OS_CHDIR      
  163.  
  164.         ld de,diskname
  165.         OS_OPENHANDLE
  166.         ld a,b
  167.         ld (diskhandle),a
  168.        
  169.         OS_NEWPAGE
  170.         ld a,e
  171.         LD (pgrom48),a
  172.         ld de,trom48
  173.         ld hl,0xc000
  174. ;de=имя файла
  175. ;hl=куда грузим (0xc000)
  176. ;a=в какой странице
  177.         call loadfile_in_ahl
  178.  
  179.         OS_NEWPAGE
  180.         ld a,e
  181.         LD (pgrom128),a
  182.         ld de,trom128
  183.         ld hl,0xc000
  184. ;de=имя файла
  185. ;hl=куда грузим (0xc000)
  186. ;a=в какой странице
  187.         call loadfile_in_ahl
  188.  
  189.         OS_NEWPAGE
  190.         ld a,e
  191.         LD (pgromDOS),a
  192.         ld de,tromDOS
  193.         ld hl,0xc000
  194. ;de=имя файла
  195. ;hl=куда грузим (0xc000)
  196. ;a=в какой странице
  197.         call loadfile_in_ahl
  198.  
  199.         OS_NEWPAGE
  200.         ld a,e
  201.         LD (pgromSYS),a
  202.         ld de,tromSYS
  203.         ld hl,0xc000
  204. ;de=имя файла
  205. ;hl=куда грузим (0xc000)
  206. ;a=в какой странице
  207.         call loadfile_in_ahl
  208.  
  209.         ;ld hl,sysvars
  210.         ;ld de,0x5b00
  211.         ;ld bc,sz_sysvars
  212.         ;ldir
  213.  
  214.         ;LD A,(curpg5);pg5
  215.         ;CALL OUTA
  216.         ;LD HL,#C000
  217.         ;LD DE,#4000
  218.         ;LD BC,#4000
  219.         ;LDIR
  220.  
  221.         call swapimer
  222.  
  223. ;хотя бы одно прерывание, чтобы захватить матрицу клавиатуры
  224.         ld b,25
  225. waitstart0
  226.         halt ;не YIELD, иначе наш обработчик не вызовется!
  227.         djnz waitstart0
  228.  
  229.        ;ld a,-1
  230.        ;ld (doson0),a
  231.         xor a
  232.         ld (doson0),a
  233.         ld (_dffd),a
  234.        ;ld a,0x10
  235.         ld (_fd),a
  236.         ;LD A,(_fd)
  237.         CALL eout7FFD
  238.  
  239.        if 0
  240.         LD HL,0
  241.         ld d,h
  242.         ld e,l
  243.         ld b,h
  244.         ld c,l
  245.         PUSH HL
  246.         POP AF
  247.         ld (immode),a
  248.         PUSH HL
  249.         POP ix
  250.         ld (_IZ),hl
  251.         ld (_AF),hl
  252.         ld (_BC),hl
  253.         ld (_DE),hl
  254.         ld (_HL),hl
  255.         EXX
  256.         EXA
  257.        endif
  258.  
  259.       IF margins
  260.        LD HL,currom
  261.        LD (curquart),HL
  262.         LD A,(HL)
  263.         OUTPGCOM
  264.         ld de,0x4000 ;пересчитанный PC
  265.       else
  266.         LD DE,0x0000 ;=PC
  267.       endif
  268.  
  269.         LD IY,EMUCHECKQ
  270.        ;EMUDATABUS ;ШД0..2 на бордюр
  271.        ;EMUADDRBUS ;ША8..10 ма бордюр
  272.        ;EMUCHECKPOINT ;проверка адреса или условия
  273.                       ;проверка числа тактов до INT?
  274. jpiyer
  275.         ld hl,jpiyer
  276.         push hl
  277.         jp (iy)
  278.  
  279. ;oldpc
  280. ;        dw 0
  281.  
  282. EMUCHECKQ
  283.        ;ld a,(0x4000)
  284.        ;or a
  285.        ;jr z,$
  286.        ;ld (oldpc),de
  287.         get
  288.         next
  289.        IF stats
  290.        PUSH HL
  291.         LD L,A
  292.         LD H,comstats/256-1
  293.         INC H
  294.         INC (HL)
  295.         jr Z,$-2
  296.        POP HL
  297.        ENDIF
  298.         LD L,A
  299.         ld H,MAINCOMS/256
  300.         LD C,(HL)
  301.         INC H
  302.         LD H,(HL)
  303.         ld L,C
  304.         JP (HL)
  305. ;можно выиграть 11(-JP=1) тактов:
  306.        ;LD L,A
  307.        ;AND 3 ;3 для JP, а можно(?) целые п/п: 7/15/31
  308.        ;ADD A,'MAINCOMS
  309.        ;LD H,A
  310.        ;JP (HL) ;L=код команды, если надо ;но надо менять обработчики, они сейчас ждут код в A!
  311. ;или ld l,a:ld h,NN:ld h,(hl):jp (hl)
  312. ;или ld l,a:or 0xc0:ld h,a:jp (hl)
  313.  
  314. CBPREFIX
  315.         get
  316.         next
  317.         LD L,A
  318.         ld H,CBCOMS/256
  319.         LD C,(HL)
  320.         INC H
  321.         LD H,(HL)
  322.         ld L,C
  323.         JP (HL)
  324.  
  325. EDPREFIX
  326.         get
  327.         next
  328.         LD L,A
  329.         ld H,EDCOMS/256
  330.         LD C,(HL)
  331.         INC H
  332.         LD H,(HL)
  333.         ld L,C
  334.         JP (HL)
  335.  
  336. FDPREFIX
  337. DDPREFIX
  338. oldprefix=$+1
  339.         CP #DD
  340.         jr Z,DDFDold
  341.         LD (oldprefix),A
  342. ;сменили префикс! меняем местами IX и _IZ
  343.         LD HL,(_IZ)
  344.         LD (_IZ),IX
  345.         PUSH HL
  346.         POP IX
  347. DDFDold
  348.         get
  349.         next
  350.         LD L,A
  351.         ld H,DDCOMS/256
  352.         LD C,(HL)
  353.         INC H
  354.         LD H,(HL)
  355.         ld L,C
  356.         JP (HL)
  357.  
  358. DDCBPREFIX
  359.         getdIXtoHL
  360.        PUSH HL
  361.         get
  362.         next
  363.         LD L,A
  364.         ld H,DDCBCOMS/256
  365.         LD C,(HL)
  366.         INC H
  367.         LD H,(HL)
  368.         ld L,C
  369.        EX (SP),HL
  370.        RET
  371.  
  372. EMUDATABUS
  373.         LD A,(DE)
  374.        OUT (-2),A
  375.         JP EMUCHECKQ
  376.  
  377. EMUADDRBUS
  378.         LD A,D
  379.        OUT (-2),A
  380.         JP EMUCHECKQ
  381.  
  382. EMUCHECKPOINT
  383. retfromim=$+1
  384.         LD HL,0
  385.         XOR A
  386.         SBC HL,DE
  387.         JP NZ,EMUCHECKQ
  388.         LD A,(_fe)
  389.        OUT (-2),A
  390.         JP EMUCHECKQ
  391.  
  392. ;OUTA
  393. ;        PUSH BC
  394. ;        OUTPG
  395. ;        POP BC
  396. ;        RET
  397.  
  398. EMUOUT
  399. ;BC=port, A=value
  400.        BIT 0,C
  401.        jp Z,eoutFE
  402.        BIT 1,C
  403.        jr Z,eoutFD
  404.         PUSH AF
  405.         LD A,(doson0)
  406.         OR A
  407.         jp Z,EMUOUTDOS
  408.         POP AF
  409.         RET
  410. eoutFD
  411.        BIT 7,B
  412.        jr Z,eout7FFD
  413.        BIT 6,B
  414.        jr NZ,eoutFFFD
  415.         LD BC,#BFFD
  416.         OUT (C),A
  417.         RET
  418. eoutFFFD
  419.        BIT 5,B
  420.        jr z,eoutDFFD
  421.         LD BC,#FFFD
  422.         OUT (C),A
  423.         RET
  424. eoutDFFD
  425.         ld (_dffd),a
  426.         ld a,(_fd)
  427. eout7FFD
  428.         LD (_fd),A
  429.         LD C,A
  430.         AND #C7
  431.         and 7
  432.         ld l,a
  433.        ld a,(_dffd)
  434.        and 3 ;Profi 512K
  435.        add a,a
  436.        add a,a
  437.        add a,a
  438.        add a,l
  439.        ld l,a
  440.         ld h,temulpgs/256
  441.         ld a,(hl)
  442. deadpg=$+1
  443.         cp 0
  444.         jr nz,eout7FFDOK
  445.        push bc
  446.        push de
  447.        push hl
  448.        exx
  449.        push bc
  450.        push de
  451.        push hl
  452.        push ix
  453.        push iy
  454.        exa
  455.        push af
  456.        OS_NEWPAGE ;мегабайт захватывать динамически постранично
  457.        pop af
  458.        exa
  459.         ld a,e
  460.        pop iy
  461.        pop ix
  462.        pop hl
  463.        pop de
  464.        pop bc
  465.        exx
  466.        pop hl
  467.        pop de
  468.        pop bc      
  469.         ld (hl),a
  470. eout7FFDOK
  471.         LD (curpghi),A
  472.        if MEM48C0
  473.         push bc
  474.         OUTPG
  475.         pop bc
  476.        endif
  477.  
  478.        LD A,(doson0) ;DOS ports on ;TODO separate flag for DOS ROM select ;TODO RAM in 0000
  479.        OR A
  480.        jr Z,eo7FFDdos
  481.         BIT 4,C ;номер ПЗУ
  482.         ld b,DOSSTATE_FROM48
  483.         LD A,(pgrom48)
  484.         jr NZ,eo7FFDo
  485.         ld b,DOSSTATE_FROM128
  486.         LD A,(pgrom128)
  487.         JR eo7FFDo
  488. eo7FFDdos
  489.         BIT 4,C ;номер ПЗУ
  490.         ld b,DOSSTATE_FROMDOS
  491.         LD A,(pgromDOS)
  492.         jr NZ,eo7FFDo
  493.         LD A,(pgromSYS)
  494.         ;JR eo7FFDo
  495. eo7FFDo
  496.         LD (currom),A
  497.         ld a,b
  498.         ld (DOSER_state),a
  499.  
  500.         LD A,C
  501.         AND 8 ;номер экрана
  502.         LD (curscr),A
  503. oldcurscr7ffd=$+1
  504.         cp 0
  505.         jr z,eo7FFDnoscr
  506.         ld (oldcurscr7ffd),a
  507.        ;push bc
  508.        push de
  509.        ;push hl
  510.        exx
  511.        push bc
  512.        push de
  513.        push hl
  514.        push ix
  515.        push iy
  516.         rrca
  517.         rrca
  518.         rrca
  519.         ld e,a
  520.        exa
  521.        push af
  522.        OS_SETSCREEN
  523.        pop af
  524.        exa
  525.        pop iy
  526.        pop ix
  527.        pop hl
  528.        pop de
  529.        pop bc
  530.        exx
  531.        ;pop hl
  532.        pop de
  533.        ;pop bc
  534. eo7FFDnoscr
  535.       if MEM48C0
  536.        if margins
  537.         CALCpgcom
  538.        else
  539. enable0000
  540.         ld a,0x3e;3a
  541.         ld (setrom),a
  542.         ld (getde0000ret),a
  543.        endif
  544.       endif
  545.         RET
  546. eoutFE
  547.         LD (_fe),A
  548. outFE
  549.         OUT (#FE),A
  550.         RET
  551. EMUOUTDOS
  552.         LD A,C
  553.         CP #3F
  554.         jr Z,eod3F
  555.         CP #5F
  556.         jr Z,eod5F
  557.         CP #FF
  558.         jr Z,eodFF
  559.         POP AF
  560.         RET
  561. eod3F
  562.         POP AF
  563.         LD (dos3F),A
  564.         RET
  565. eod5F
  566.         POP AF
  567.         LD (dos5F),A
  568.         RET
  569. eodFF
  570.         POP AF
  571.         LD (dosFF),A
  572.         RET
  573.  
  574. EMUIN
  575. ;BC=port
  576. ;return A=value
  577.        BIT 0,C
  578.        jr Z,einFE
  579.         LD A,(doson0)
  580.         OR A
  581.         jr Z,EMUINDOS
  582.        LD A,C
  583.        cp 0xfd
  584.        jr z,einAY
  585.        CP #DF
  586.        jr Z,einMOUSE
  587.        CP #1F
  588.        jr Z,einKEMPSTON
  589.         LD A,#FF
  590.         RET
  591. einAY
  592.         ld bc,0xfffd
  593.         in a,(c)
  594.         ret
  595. einMOUSE
  596.        LD A,B
  597.        CP #FA
  598.        jr Z,einFADF
  599.        CP #FB
  600.        jr Z,einFBDF
  601.        CP #FF
  602.        jr Z,einFFDF
  603.         LD A,#FF
  604.         RET
  605. einFADF
  606.         ;LD BC,#FADF
  607.         ;IN A,(C)
  608. mousebuttons=$+1
  609.         ld a,0xff
  610.         RET
  611. einFBDF
  612.         ;LD BC,#FBDF
  613.         ;IN A,(C)
  614. mousex=$+1
  615.         ld a,0
  616.         RET
  617. einFFDF
  618.         ;LD BC,#FFDF
  619.         ;IN A,(C)
  620. mousey=$+1
  621.         ld a,0
  622.         RET
  623. einKEMPSTON
  624.         ;IN A,(#1f)
  625. kempston=$+1
  626.         ld a,0
  627.         RET
  628. einFE
  629.         ;LD C,#FE
  630.         ;IN A,(C)
  631.         ;ld a,b
  632.         ;or a
  633.         ;jr z,$
  634.        push hl
  635.        ld hl,keymatrix
  636.        ld a,0xff
  637.        dup 8
  638.        rlc b
  639.        jr c,$+3
  640.        and (hl)
  641.        inc hl
  642.        edup
  643.        pop hl
  644.        and a
  645.         ;LD C,#FE
  646.         ;IN A,(C)
  647.         RET
  648. EMUINDOS
  649.         LD A,C
  650.         CP #1F
  651.         jr Z,eid1F
  652.         CP #3F
  653.         jr Z,eid3F
  654.         CP #5F
  655.         jr Z,eid5F
  656.         CP #5F
  657.         jr Z,eidFF
  658.         LD A,#FF
  659.         RET
  660. eidFF
  661.         ;LD A,#80 ;INTRQ=команда выполнена ok
  662.         ld a,r
  663.         rla
  664.         and 0xc0 ;D6=DRQ, D7=INTRQ
  665.         RET
  666. eid1F
  667.         ;LD A,#80 ;команда выполнена ok, диск вставлен
  668.         ld a,r
  669. fddstatemask=$+1
  670.         and 3
  671.         or 0x80
  672.         RET
  673. eid3F
  674.         LD A,(dos3F) ;trk
  675.         RET
  676. eid5F
  677.         LD A,(dos5F) ;sec
  678.         RET
  679.  
  680. keymatrix
  681.         ds 8,0xff
  682.  
  683.        if 0
  684. imitret
  685.         LD HL,(_SP)
  686.         getmemBC
  687.         LD (_SP),HL
  688.         ld d,b
  689.         ld e,c
  690.        _LoopC_JP
  691.        endif
  692.  
  693. DOSrdindex
  694.         LD A,E
  695.         cp #08
  696.         jr z,DOSsetheadwait
  697.         CP #b2 ;#3eb2
  698.         jr nz,jpiy;ret nz
  699. ;Адрес #3EB2. Проверка индексной области дорожки. Установите #5CD1 и поместите в B время перемещения головки дисковода. Выбирается верхняя сторона и при ошибке в #5D17 помещается #FF. В регистр H помещается номер текущей дорожки. Используется также с адреса: #3EE7 (обработка ошибки NO DISC).
  700.        ld a,(dos3F) ;trk
  701.        exx
  702.        ld h,a
  703.        exx
  704.         jp imitret
  705. DOSsetheadwait
  706.         ld a,3
  707.         ld (fddstatemask),a ;костыль!!!
  708.         jp imitret
  709.  
  710. DOSER
  711. ;после каждой команды, меняющей PC ;выход по jp (iy)
  712. ;если мы не в досе, то проверяем, что D=#3D
  713. ;если мы в досе, то проверяем, что D<=#40
  714. ;если мы в 128K (TODO или в ОЗУ 0000), то ничего не делаем
  715. DOSSTATE_FROM48=0x18 ;jr DOSERny
  716. DOSSTATE_FROMDOS=0x3e ;ld a,N (skip jr)
  717. DOSSTATE_FROM128=0xc9 ;ret
  718.         ;LD A,(doson0)
  719.         ;OR A
  720.         ;jr NZ,DOSERny
  721. DOSER_state=$
  722.         jr DOSERny
  723.        if margins
  724.         ld a,(curquart)
  725.         cp 3 ;0000?
  726.         jr z,DOSDOS ;DOS -> DOS
  727.        else
  728.         LD A,D
  729.         CP #40
  730.         jr C,DOSDOS ;DOS -> DOS
  731.        endif
  732. ;DOS -> неDOS
  733. ;выкл. стр. доса
  734.         LD A,-1
  735.         LD (doson0),A ;DOS ports off
  736.         ld a,DOSSTATE_FROM48
  737.         ld (DOSER_state),a
  738.         LD A,(_fd)
  739.         call eout7FFD
  740. jpiy
  741.         jp (iy)
  742. DOSDOS
  743.   ;для SYS не перехватываем!
  744.         LD A,(_fd)
  745.         AND 16
  746.         jr z,jpiy;RET Z
  747.         ld a,d
  748. ;перехваты процедур доса
  749.        if margins
  750.         cp 0x3e+0x40
  751.        else
  752.         cp 0x3e
  753.        endif
  754.         jr z,DOSrdindex
  755.        if margins
  756.         cp 0x3f+0x40
  757.        else
  758.         cp 0x3f
  759.        endif
  760.         jr nz,jpiy;RET NZ ;не перехватываем
  761. ;имитировать RET после неё
  762.         LD A,E
  763.         CP #D5 ;#3fd5
  764.         jr Z,DOSRD
  765.         CP #E5 ;#3fe5
  766.         jr Z,DOSRD
  767.         CP #BA ;#3fba
  768.         jr z,DOSWR
  769.         jp (iy) ;RET NZ
  770. DOSRD
  771.         xor a
  772.         ld (fddstatemask),a ;костыль!!! иначе читает через раз
  773.      PUSH DE,IX,IY
  774.         EXX
  775.         PUSH HL
  776.         INC H
  777.         EXX
  778.         POP HL
  779.         LD C,5
  780.         LD A,(dos3F) ;trk
  781.         ADD A,A
  782.         LD D,A
  783.         LD A,(dosFF)
  784.         BIT 4,A
  785.         jr nz,$+3
  786.         INC D
  787.         LD A,(dos5F) ;sec
  788.         DEC A
  789.         LD E,A
  790.         CALL DOSrdsec
  791.      POP IY,IX,DE
  792. DOSWR
  793. ;TODO
  794.         jp imitret
  795.  
  796. DOSERny
  797. ;from 48/RAM
  798.        if margins
  799.         ld a,d
  800.         cp 0x3d+0x40
  801.         jr nz,jpiy;RET NZ
  802.         ld a,(curquart)
  803.         cp 3 ;0000?
  804.         jr nz,jpiy;RET NZ
  805.        else
  806.         LD A,D
  807.         CP #3D
  808.         jr nz,jpiy;RET NZ
  809.        endif
  810.   ;для 128 васика запрещено! иначе глючит калькулятор
  811.         ;LD A,(_fd)
  812.         ;AND 16
  813.         ;RET Z
  814. ;неDOS -> DOS
  815.        LD A,E
  816.        CP #13
  817.        jr Z,DOS3D13 ;если убрать, будет значительно медленнее
  818. DOSSWON
  819. ;вкл. стр. доса
  820. ;имитация RET не катит для точки #3D2F
  821.         XOR A
  822.         LD (doson0),A ;DOS ports on
  823.         ld a,DOSSTATE_FROMDOS
  824.         ld (DOSER_state),a
  825.         LD A,(_fd)
  826.         call eout7FFD
  827.         jp (iy)
  828. DOS3D13
  829.         exx
  830.         ld a,c
  831.         exx
  832.         cp 6
  833.         jr z,DOSWRSEC
  834.         cp 5
  835.         jr nz,DOSSWON ;(for other functions)
  836. DOSRDSEC
  837. DOSWRSEC
  838.         exx
  839. D3D5S0
  840.         CALL DOSrdsec ;c=5(read)/6(write)
  841.         inc h
  842.         inc e
  843.         bit 4,e
  844.         jr z,$+5
  845.         inc d
  846.         ld e,0
  847.         DJNZ D3D5S0
  848. ;write de to virtual 23796:
  849.         ld hl,23796
  850.         ld b,d
  851.         ld c,e
  852.         putmemBC
  853.         exx
  854.        jp imitret ;имитировать RET после неё
  855.  
  856. DOSrdsec
  857. ;hl=addr
  858. ;d=track
  859. ;e=sector
  860. ;c=5(read)/6(write)
  861.        PUSH BC
  862.        PUSH de
  863.        PUSH HL
  864.        EXX
  865.        EXA
  866.         PUSH AF
  867.         PUSH BC,DE,HL
  868.         push ix,iy
  869.        EXA
  870.        EXX
  871.         push hl ;addr
  872.         ld a,e ;de=trsec
  873.         add a,a
  874.         add a,a
  875.         add a,a
  876.         add a,a
  877.         ld l,d ;track
  878.         ld h,0 ;0la=trsec*16
  879.         dup 4
  880.         add a,a
  881.         adc hl,hl
  882.         edup ;hl0=trsec*256
  883.         ld d,a;0
  884.         ld e,h
  885.         ld h,l
  886.         ld l,a;0 ;dehl=shift in file
  887. diskhandle=$+1
  888.         ld b,0
  889.        push bc ;c=5/6
  890.         OS_SEEKHANDLE
  891.        pop bc ;c=5/6, b=handle
  892.         pop hl ;addr
  893.        bit 0,c
  894.        jr nz,DOSrdsec5
  895.         ld de,secbuf
  896.         push bc
  897.         push de
  898.         ld b,0
  899. DOSwrseccopy0
  900.         push bc
  901.         push hl
  902.         getmem
  903.         ld (de),a
  904.         pop hl
  905.         pop bc
  906.         inc hl
  907.         inc de
  908.         djnz DOSwrseccopy0
  909.         pop de ;secbuf
  910.         pop bc ;b=handle
  911.         ld hl,256 ;de=phys addr ;hl=size
  912.         OS_WRITEHANDLE
  913.        jr DOSrdsec5ok
  914. DOSrdsec5
  915.          push hl ;addr
  916.          ld de,secbuf
  917.          push de
  918.         ld hl,256 ;size
  919.         OS_READHANDLE
  920.          pop hl ;secbuf
  921.          pop de ;addr
  922.         ex de,hl ;de->hl
  923.         ld b,0
  924. DOSrdseccopy0
  925.         push bc
  926.         push hl
  927.         ld a,(de)
  928.         putmem
  929.         pop hl
  930.         pop bc
  931.         inc hl
  932.         inc de
  933.         djnz DOSrdseccopy0
  934. DOSrdsec5ok
  935.        exx
  936.        EXA
  937.         pop iy,ix
  938.         pop hl,de,bc
  939.         pop af
  940.        EXA
  941.        EXX
  942.         pop hl,de,bc    
  943.         ret
  944.  
  945.         INCLUDE "disasm.asm"
  946.  
  947.         INCLUDE "z80cmd.asm"
  948.         align 256
  949.         INCLUDE "z80table.asm"
  950.         DISPLAY $
  951.        IF stats
  952.         align 256
  953. comstats
  954.         DISPLAY "comstats=",$
  955.         DS #400
  956.        ENDIF
  957.  
  958.         include "rst38.asm"
  959.  
  960. on_int
  961.         ;jp IMER
  962. ;IMER
  963.         PUSH AF,HL
  964.         push bc,de
  965.         exx
  966.         push bc
  967.         push de
  968.         push hl
  969.         push ix
  970.         push iy
  971.         ex af,af' ;'
  972.         push af
  973.  
  974.         ld a,(curscr)
  975. oldcurscr=$+1
  976.         cp 0
  977.         jr z,IMERnoscr
  978.         ld (oldcurscr),a
  979.         rrca
  980.         rrca
  981.         rrca
  982.         ld e,a
  983.         OS_SETSCREEN
  984. IMERnoscr
  985.  
  986.         ld a,(_fe)
  987.         and 7
  988. oldcurborder=$+1
  989.         cp 0
  990.         jr z,IMERnoborder
  991.         ld (oldcurborder),a
  992.         ld e,a
  993.         OS_SETBORDER
  994. IMERnoborder
  995.         call oldimer
  996.  
  997.        if 0
  998.         ld bc,0x7ffe
  999.         in a,(c)
  1000.         ld lx,a  ;lx=%???bnmS_
  1001.         ld b,0xbf
  1002.         in a,(c)
  1003.         ld hx,a  ;hx=%???hjklE
  1004.         ld b,0xdf
  1005.         in l,(c)  ;l=%???yuiop
  1006.         ld b,0xef
  1007.         in h,(c)  ;h=%???67890
  1008.         ld b,0xf7
  1009.         in e,(c)  ;e=%???54321
  1010.         ld b,0xfb
  1011.         in d,(c)  ;d=%???trewq
  1012.         ld a,0xfd
  1013.         in a,(0xfe);c=%???gfdsa
  1014.         ld b,c;0xfe
  1015.         in b,(c)  ;b=%???vcxzC
  1016.         ld c,a
  1017.        else
  1018.         OS_GETKEYMATRIX ;out: bcdehlix = halfrows cs...space
  1019.        endif
  1020.         ld (keymatrix),ix
  1021.         ld (keymatrix+2),hl
  1022.         ld (keymatrix+4),de
  1023.         ld (keymatrix+6),bc
  1024.         OS_GETKEY
  1025. ;        A - код символа(кнопки). Допустимые коды смотри в 'sysdefs.asm' секция 'Usable key codes'
  1026. ;        C - код символа(кнопки) без учета текущего языкового модификатора. Как правило, используется дляи обработки "горячих кнопок"
  1027. ;        DE - позиция мыши (y,x) (возвращает 0 при отсутствии фокуса)
  1028. ;        L - кнопки мыши (bits 0(LMB),1(RMB),2(MMB): 0=pressed; bits 7..4=положение колёсика)
  1029. ;        LX - Kempston joystick (0bP2JFUDLR): 1=pressed, - при отсутствии джойстика 0 (а не 0xff)
  1030. ;        Флаг Z - если 0(NZ), то отсутствует фокус.
  1031.         jr nz,IMERnofocus
  1032.         ld a,e
  1033.         ld (mousex),a
  1034.         ld a,d
  1035.         ld (mousey),a
  1036.         ld a,l
  1037.         ld (mousebuttons),a
  1038.         ld a,lx
  1039.         ld (kempston),a
  1040. IMERnofocus
  1041.  
  1042. ;TODO здесь опрос клавиш эмулятора
  1043.  
  1044.         pop af
  1045.         ex af,af' ;'
  1046.         pop iy
  1047.         pop ix
  1048.         pop hl
  1049.         pop de
  1050.         pop bc
  1051.         exx
  1052.         pop de,bc      
  1053.        LD A,(iff1)
  1054.        OR A
  1055.        jr NZ,IMEREI
  1056.         POP HL,AF
  1057.         EI
  1058.         RET
  1059. IMEREI
  1060.         XOR A
  1061.         LD (iff1),A
  1062.         LD (iff2),A ;для NMI надо только iff1!
  1063. ;перед эмуляцией INT завершаем тек.команду (перехват на EMULOOP)
  1064.         LD (keepemuchecker),IY
  1065.         LD IY,IMINT
  1066.         POP HL,AF
  1067.         RET  ;di!
  1068. IMINT
  1069. keepemuchecker=$+2
  1070.         LD IY,0
  1071.        LD (retfromim),DE ;для индикации времени обработки прерыв
  1072.        LD A,(immode)
  1073.        CP #18 ;IM2
  1074.         LD HL,#38 ;new PC
  1075.        jr NZ,IMERIM1
  1076.         LD HL,(_I-1)
  1077.         LD L,#FF ;состояние пассивной ШД
  1078.         getmemBC
  1079.         ld h,b
  1080.         ld l,c
  1081.         JR IMERIM
  1082. GETIY
  1083.         LD HL,(_IZ)
  1084.         LD A,(oldprefix)
  1085.         CP #DD
  1086.         RET Z
  1087.         PUSH IX
  1088.         POP HL
  1089.         RET
  1090. IMERIM1
  1091.      IF skipIM1
  1092.        PUSH HL
  1093.         CALL GETIY
  1094.         LD BC,23610
  1095.         OR A
  1096.         SBC HL,BC
  1097.        POP HL
  1098.         JR NZ,IMERIM
  1099. ;вообще-то надо и SP проверить...
  1100.     IF extpg5
  1101.         PUSH DE
  1102.         LD A,(curpg5)
  1103.         CALL OUTA
  1104.         LD DE,#5C00
  1105.         LD HL,#DC00
  1106.         LD BC,146
  1107.         LDIR
  1108.     ENDIF
  1109.       push ix
  1110.       PUSH IY
  1111.      if MEM48C0
  1112.         call set4000
  1113.      endif
  1114.       LD IY,23610
  1115.       call L0038;basicrst38
  1116.       LD A,-1
  1117.       LD (iff1),A
  1118.       LD (iff2),A
  1119.       POP IY
  1120.       pop ix
  1121.     IF extpg5
  1122.         LD HL,#5C00
  1123.         LD DE,#DC00
  1124.         LD BC,146
  1125.         LDIR
  1126.         POP DE
  1127.     ENDIF
  1128.      _LoopC ;RET уже был (адрес со стека снят)
  1129.      ENDIF
  1130. IMERIM
  1131. ;hl=new PC
  1132.         EI
  1133.        CALCpc ;de=old PC
  1134.         ex de,hl ;DE=new PC
  1135.         LD B,H
  1136.         ld C,L ;BC=old PC
  1137.         LD HL,(_SP)
  1138.         DEC HL,HL
  1139.         LD (_SP),HL
  1140.         putmemBC
  1141.        _LoopC_JP
  1142.  
  1143.        if MEM48C0      
  1144. setmem00004000forwrite
  1145. ;NC, keep CY (keep A for rra:ld h,a)
  1146. ;если 0000 (p) и включено ПЗУ, то должен ld h,secbuf/256
  1147. ;иначе setmem00004000
  1148. ROMSTATE_ON=0xf2 ;jp p
  1149. ROMSTATE_OFF=0xda ;jp c
  1150. romstate=$
  1151.         jp p,setmem00004000forwrite_skip
  1152. setmem00004000
  1153.         jp m,set4000forwrite
  1154.         set 6,h
  1155. setrom
  1156.        if !margins
  1157.         ld a,0xc9 ;/RET
  1158.         ld (setrom),a
  1159.         ld (getde0000ret),a
  1160.         ld a,0x3e;3a
  1161.         ld (set4000),a
  1162.         ld (set4000forwrite),a
  1163.        endif
  1164.         ld a,(currom) ;0000
  1165.        push bc
  1166.         OUTPG4000
  1167.        pop bc
  1168.        ld a,h
  1169.        sub 64
  1170.        add a,a
  1171.         ret
  1172. setmem00004000forwrite_skip
  1173.         ld h,secbuf/256
  1174.         ret
  1175.  
  1176. set4000forwrite
  1177.        if !margins
  1178.         ld a,0xc9 ;/RET
  1179.         ld (set4000),a
  1180.         ld (set4000forwrite),a
  1181.         ld a,0x3e;3a
  1182.         ld (setrom),a
  1183.         ld (getde0000ret),a
  1184.        endif
  1185.         ld a,(curpg5) ;4000
  1186.        push bc
  1187.         OUTPG4000
  1188.        pop bc
  1189.        ld a,h
  1190.        add a,a
  1191.         ret
  1192.  
  1193. set4000
  1194.        if !margins
  1195.         ld a,0xc9 ;/RET
  1196.         ld (set4000),a
  1197.         ld (set4000forwrite),a
  1198.         ld a,0x3e;3a
  1199.         ld (setrom),a
  1200.         ld (getde0000ret),a
  1201.        endif
  1202.         ld a,(curpg5) ;4000
  1203.        push bc
  1204.         OUTPG4000
  1205.        pop bc
  1206.          ld a,(de) ;for getde00004000
  1207.         ret
  1208.  
  1209. getde0000l_getde00004000
  1210.         call getde0000
  1211.         ld l,a
  1212.        inc de
  1213.         ld a,d
  1214.         add a,a ;check 3fff->4000
  1215. getde00004000
  1216.         jp m,set4000
  1217. getde0000
  1218.        if !margins
  1219.         set 6,d
  1220.         ld a,(de)
  1221.         res 6,d ;fastest branch! no extra commands!
  1222. getde0000ret
  1223.         ld a,0xc9 ;/RET
  1224.         ld (setrom),a
  1225.         ld (getde0000ret),a
  1226.         ld a,0x3e;3a
  1227.         ld (set4000),a
  1228.         ld (set4000forwrite),a
  1229.        endif
  1230.         ld a,(currom) ;0000
  1231.         OUTPG4000
  1232.         set 6,d
  1233.         ld a,(de)
  1234.         res 6,d
  1235.         ret
  1236.        
  1237.        endif
  1238.  
  1239.        if margins
  1240. next_incd
  1241.         inc d
  1242.         ret nz
  1243.         ld d,0xc0
  1244.         ld hl,(curquart)
  1245.         inc l
  1246.         res 2,l
  1247.         ld (curquart),hl
  1248.         ld a,(hl)
  1249.         OUTPGCOM
  1250.         ret
  1251.        endif
  1252.  
  1253.         align 256
  1254. temulpgs
  1255.         ds 64 ;пока используем 8
  1256.  
  1257. pgrom48
  1258.         db 0
  1259. pgrom128
  1260.         db 0
  1261. pgromDOS
  1262.         db 0
  1263. pgromSYS
  1264.         db 0
  1265.        
  1266. _AF     DW 0 ;AF'
  1267. _BC     DW 0 ;BC'
  1268. _DE     DW 0 ;DE'
  1269. _HL     DW 0 ;HL'
  1270. _SP     DW 0
  1271. _IZ     DW 0
  1272. _R      DB 0
  1273. _I      DB 0
  1274. iff1    DB 0
  1275. iff2    DB 0
  1276. immode  DB 0 ;#18=IM2, иначе IM1
  1277. _fd     DB 0;#10 ;с точки зрения эмулимой проги
  1278. _dffd   db 0
  1279. _fe     DB 0
  1280. dos3F   DB 0
  1281. dos5F   DB 0
  1282. dosFF   DB 0
  1283.  
  1284.        if margins
  1285. curquart
  1286.         DW currom
  1287.         align 256
  1288.        endif
  1289.  
  1290. ;реальные банки (лежат подряд для margins)
  1291. curpg5  DB 0 ;for 4000
  1292. curpg2  DB 0 ;for 8000
  1293. curpghi DB 0 ;for c000
  1294. currom  DB 0 ;for 0000
  1295.  
  1296. curscr  DB 0 ;0/8
  1297.  
  1298. ;romon0  DB 0 ;#C0=ОЗУ, 0=ПЗУ в нижних 16k ;теперь в romstate
  1299. doson0  DB 0;-1 ;0=SYS/DOS, -1=48/128
  1300.  
  1301. loadfile_in_ahl
  1302. ;de=имя файла
  1303. ;hl=куда грузим (0xc000)
  1304. ;a=в какой странице
  1305.         SETPGC000 ;включили страницу A в 0xc000
  1306.         push hl ;куда грузим
  1307.         OS_OPENHANDLE
  1308.         pop de ;куда грузим
  1309.         push bc ;b=handle
  1310.         ld hl,0x4000 ;столько грузим (если столько есть в файле)
  1311.         OS_READHANDLE
  1312.         pop bc ;b=handle
  1313.         OS_CLOSEHANDLE
  1314.         ret;jp setpgmainc000 ;включили страницу программы в c000, как было
  1315.  
  1316. path
  1317.         db "z80",0
  1318.  
  1319. diskname
  1320.         db "SYS.TRD",0
  1321.        
  1322. trom48
  1323.         ;DB "2006.ROM",0
  1324.         ;DB "1982.ROM",0
  1325.         DB "48for128.rom",0
  1326.         ;DB "testatm.rom",0
  1327. trom128
  1328.         DB "128tr.rom",0
  1329.         ;DB "testatm.rom",0
  1330. tromSYS
  1331.         DB "GLUKPEN.ROM",0
  1332.         ;DB "testatm.rom",0
  1333. tromDOS
  1334.         DB "DOS6_10E.ROM",0
  1335.         ;DB "testatm.rom",0
  1336.  
  1337.         if 0
  1338. sysvars
  1339.         incbin "goodsysv"
  1340. sz_sysvars=$-sysvars
  1341.         endif
  1342.  
  1343. swapimer
  1344.         di
  1345.         ld de,0x0038
  1346.         ld hl,oldimer
  1347.         ld bc,3
  1348. swapimer0
  1349.         ld a,(de)
  1350.         ldi ;[oldimer] -> [0x0038]
  1351.         dec hl
  1352.         ld (hl),a ;[0x0038] -> [oldimer]
  1353.         inc hl
  1354.         jp pe,swapimer0
  1355.         ei
  1356.         ret
  1357. oldimer
  1358.         jp on_int
  1359.         jp 0x0038+3
  1360.  
  1361. end
  1362.  
  1363.         align 256 ;for setmem00004000forwrite
  1364. rrdbuf  ;DB 0
  1365. secbuf
  1366.         ds 256
  1367.         display secbuf+256
  1368.  
  1369.         savebin "z80.com",begin,end-begin
  1370.  
  1371.         LABELSLIST "../../us/user.l"
  1372.