?login_element?

Subversion Repositories NedoOS

Rev

Rev 555 | Rev 594 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.         DEVICE ZXSPECTRUM128
  2.         include "../../_sdk/sys_h.asm"
  3.  
  4. Z80=1
  5. Z80ATTR=1
  6. Z80OPT=1 ;не влияет?
  7. Z80OPT2=1 ;не влияет?
  8. Z80OPT2bug=1 ;при 1 черепахи не сталкиваются друг об друга (там записана дема в 3-3, TODO переделать дему) - в релизе включать не надо!!!
  9. Z80OPT2a=1 ;не влияет?
  10. Z80OPT3=1 ;распаковка карты  - не влияет?
  11. Z80OPT3ly=1 ;не влияет?
  12. Z80OPT3hy=1 ;не влияет?
  13. Z80OPT3hybug=1 ;при 1 не падает в первую яму в 1-4, а должен (задержка старта уровня на несколько фреймов, а карта та же) - в релизе включать не надо!!!
  14. Z80OPT4=1 ;вывод распакованной карты - не влияет?
  15.  
  16. Z80MARIOCOLOR=1
  17. Z80BGCOLOR=1
  18. Z80MARIOCYCLECOLOR=1
  19. Z80COINCYCLECOLOR=1
  20.  
  21. INFINITELIVES=1
  22. NOPIRANHAPLANT=0 ;нет кактуса
  23. GOODPIRANHAPLANT=1 ;кактус и плевок лавы не убивают (для демы)
  24. GOODBULLET=0 ;пуля не убивает (не помогает для демы 8-2 при MULTITASKING)
  25. ALWAYSPRINCESS=0;1 ;no mushroom retainer (Toad), princess in every level-4
  26.  
  27. FASTDEMOBEFOREBREAKPOINT=0;1 ;(без костыля влияет на прохождение 1-2 при MUSICONINT=1) до брякпоинта в деме (прописывается как reset, т.е. вторая клеточка) реже работает видеоконтроллер
  28. ;при запуске грузится дема antipac.fm2 - если её нет, то включается режим записи
  29. ;кнопки: стрелки, a="A", s="B", Enter="START", Space="SELECT"
  30. ;Esc (Break, Caps Shift + Space) - выход в OS
  31. ;C=продолжить показ демы после брякпоинта
  32. ;D=прервать показ демы (включается запись с клавиатуры с этого же места)
  33. ;V=записать на диск текущее записанное demo.fb2 (добавленные строчки с плюсиками)
  34. ;демы пишем так:
  35. ;- ставим в текущую дему в нужном месте брякпоинт (|.r|)
  36. ;запускаем с FASTDEMOBEFOREBREAKPOINT=1
  37. ;когда появляется изображение, жмём D, играем
  38. ;после ошибки жмём V (сохранение)
  39. ;экстрактим demo.fm2
  40. ;ищем строчку с |.r|
  41. ;исправляем следующую строчку на пустую? (сейчас вроде и так пустая)
  42. ;копируем из demo.fm2 то, что после |.r| до ошибки, в текущую дему, строчку с |.r| вообще стираем (она не участвует в таймингах игры)
  43.  
  44.         ;include "6502.asm"
  45.         include "6502fast.asm"
  46.  
  47. RESTOREPG16K=1
  48. MUSIC=1
  49. MUSICONINT=0;1
  50.  
  51. OSCALLS=0
  52. MULTITASKING=1 ;при MUSICONINT=1 влияет на прохождение 8-2 в деме (место облома зависит от числа тактов!), даже костыль мало помогает, приходится делать GOODBULLET
  53.         ;display "OSCALLS=",OSCALLS
  54.  
  55. SWEEP=0
  56.  
  57. DEMO=1
  58.  
  59. tempintstack=0x4000 ;2 bytes
  60. STACK=0x3ffe
  61. INTSTACK=0x3f00
  62. scrbase=0x8000
  63.  
  64. scrwid=320
  65. scrhgt=200
  66. ;title safe area 224x192 (не видно 3 верхних знакоместа)
  67. ;добавим внизу ещё 8 пикс. под ямы
  68. YSKIPFROMTOP=2;3
  69.  
  70. ;font=0x4000+0x2000 ;TODO
  71.  
  72. COMPACTDATA=0 ;1 портит память после прерывания демы
  73. SCRATCHPAD=0x100 ;в оригинале 0x000
  74.  
  75. ENDLINETILE=0xff;10+('J'-'A');0xff ;letter 'J' unused
  76. EMPTYTILE=0x24 ;там и было в оригинале
  77. FASTEMPTYTILES=1
  78.  
  79.         org PROGSTART
  80. begin
  81.         OS_HIDEFROMPARENT
  82.         ld e,0
  83.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  84.         ld e,0 ;color byte
  85.         OS_CLS
  86.         ld e,1
  87.         OS_SETSCREEN
  88.         ld e,0 ;color byte
  89.         OS_CLS
  90.  
  91.         OS_GETMAINPAGES
  92. ;dehl=номера страниц в 0000,4000,8000,c000
  93.         ld a,e
  94.         ld (codepage4000),a
  95.         ld a,h
  96.         ld (codepage8000),a
  97.         ld a,l
  98.         ld (codepagec000),a
  99.         OS_NEWPAGE
  100.         ld a,e
  101.         ld (tilepage),a
  102.         OS_NEWPAGE
  103.         ld a,e
  104.         ld (spritepage),a
  105.         OS_NEWPAGE
  106.         ld a,e
  107.         ld (spritepagemirver),a
  108.         OS_NEWPAGE
  109.         ld a,e
  110.         ld (spritepagemirhor),a
  111.         OS_NEWPAGE
  112.         ld a,e
  113.         ld (spritepagemirhorver),a
  114.         OS_NEWPAGE
  115.         ld a,e
  116.         ld (pgtileprocL),a
  117.         OS_NEWPAGE
  118.         ld a,e
  119.         ld (pgtileprocR),a
  120.         OS_NEWPAGE
  121.         ld a,e
  122.         ld (pgaddrstack),a
  123.         OS_NEWPAGE
  124.         ld a,e
  125.         ld (pgaddrstackcopy),a
  126.        
  127.         ;OS_GETSCREENPAGES
  128. ;de=страницы 0-го экрана (d=старшая), hl=страницы 1-го экрана (h=старшая)
  129.         ;ld a,e
  130.         ;ld (setpgs_scr_low),a
  131.         ;xor l
  132.         ;ld (setpgs_scr_low_xor),a
  133.         ;ld a,d
  134.         ;ld (setpgs_scr_high),a
  135.         ;xor h
  136.         ;ld (setpgs_scr_high_xor),a
  137.  
  138.         ld de,gfxfilename
  139.         call openstream_file
  140.         or a
  141.         jp nz,noloadgfx
  142. ;skip 0x8010 bytes
  143.         ld de,0
  144.         ld hl,0x8010
  145.         ;dehl=shift
  146.         ld a,(filehandle)
  147.         ld b,a
  148.         OS_SEEKHANDLE
  149.         ld de,tilegfx
  150.         ld hl,0x2000
  151. ;DE = Buffer address, HL = Number of bytes to read
  152.         call readstream_file
  153.         call closestream_file
  154.        
  155.         ld hl,0x2000+TitleScreenDataOffset
  156.         ld de,TitleScreen
  157.         ld bc,TitleScreenDataSize
  158.         ldir
  159.  
  160.         call copytilesgfx
  161.        
  162.         ld a,(tilepage)
  163.         SETPG16K ;stack in 0xfffx
  164.         call recodetiles
  165.        
  166.         ld a,(spritepage)
  167.         SETPG16K ;stack in 0xfffx
  168.         call recodesprites
  169.        
  170.         call mirspritesver
  171.  
  172.         ld a,(spritepagemirver)
  173.         SETPG16K ;stack in 0xfffx
  174.         call recodesprites
  175.        
  176.         call mirspriteshor
  177.  
  178.         ld a,(spritepagemirhorver)
  179.         SETPG16K ;stack in 0xfffx
  180.         call recodesprites
  181.        
  182.         call mirspritesver
  183.  
  184.         ld a,(spritepagemirhor)
  185.         SETPG16K
  186.         call recodesprites
  187.        
  188. ;result in 0x4000: 32bytes/tile
  189.        
  190.         ld sp,STACK
  191.        
  192.        
  193.         ld de,filename
  194.         call openstream_file
  195.         or a
  196.         jr nz,noloaddemo
  197.        
  198.         ld hl,0
  199.         ld de,0
  200. nvview_load0
  201.         push de
  202.         push hl
  203.         call reservepage
  204.         pop hl
  205.         pop de
  206.         ret nz ;no memory
  207.         push de
  208.         push hl
  209.         ld de,0xc000
  210.         ld hl,0x4000
  211. ;DE = Buffer address, HL = Number of bytes to read
  212.         push hl
  213.         call readstream_file
  214. ;hl=loaded bytes
  215.         ld b,h
  216.         ld c,l
  217.         pop hl ;Number of bytes to read
  218.         or a
  219.         sbc hl,bc ;z=loaded as requested
  220. ;bc=loaded bytes
  221.         pop hl
  222.         pop de
  223. ;hlde=size
  224. ;z=loaded as requested
  225.         ex de,hl
  226.         add hl,bc
  227.         ex de,hl
  228.         jr nc,$+3
  229.         inc hl
  230.         jr z,nvview_load0
  231. ;hlde=true file size (for TRDOSFS)
  232.         ;ld (fcb+FCB_FSIZE),de
  233.         ;ld (fcb+FCB_FSIZE+2),hl
  234.  
  235.         call closestream_file
  236.  
  237.         jr loaddemoq
  238. noloaddemo
  239.         call demooff
  240. loaddemoq
  241.        
  242.        
  243.        
  244.         call gentileproc_all
  245.         call genaddrstack
  246.  
  247.         call shutay
  248.  
  249.         ld e,13
  250.         ld bc,0xfffd
  251.         out (c),e
  252.         ld a,0x08 ;sawtooth
  253.         ld b,0xbf
  254.         out (c),a
  255.  
  256.         ld de,mariopal
  257.         OS_SETPAL
  258.         ;OS_GETTIMER ;hlde=timer
  259.         ;ld (oldtimer),de
  260.         YIELD ;иначе палитра не установится
  261.        
  262.         call setpgs_code
  263.         call swapimer
  264.        
  265.         jp Start
  266.  
  267. mirspriteshor
  268.         ld hl,0x2000
  269.         ld bc,0x1000
  270. mirspriteshor0
  271.         ld e,(hl)
  272.         ld a,1
  273. mirspriteshor00
  274.         rr e
  275.         rla
  276.         jr nc,mirspriteshor00
  277.         ld (hl),a
  278.         cpi
  279.         jp pe,mirspriteshor0
  280.         ret
  281.        
  282. mirspritesver
  283.         ld de,0x2000
  284. ;sprite gfx: 256 tiles *2 (high, low bitchars)
  285. mirspritesver0
  286.         ld h,d
  287.         ld l,e
  288.         ld bc,4
  289.         add hl,bc
  290.         add hl,bc
  291.         push hl
  292. mirspritesver00
  293.         dec hl
  294.         ld a,(de)
  295.         ldi
  296.         dec hl
  297.         ld (hl),a
  298.         jp pe,mirspritesver00
  299.         pop de
  300.         bit 4,d ;<0x3000
  301.         jr z,mirspritesver0
  302.         ret
  303.        
  304. recodesprites
  305.         ld hl,0x2000
  306.         ld de,0x4000
  307. ;sprite gfx: 256 tiles
  308.         ld hy,_K;_1 ;_3 too dark
  309.         ld hx,0 ;256
  310. recodesprites0
  311.         push hl
  312.         add hl,hl
  313.         add hl,hl
  314.         add hl,hl
  315.         add hl,hl
  316.         ld l,h ;номер тайла
  317.         ld h,tileattr/256+1
  318.         ld a,(hl) ;номер палитры
  319.         ld hy,a
  320.         pop hl
  321.         call recodesprite
  322.         dec hx;bit 6,h ;<0x4000
  323.         jr nz,recodesprites0
  324.         ret
  325.  
  326. recodetiles
  327.         ld hl,0x3000
  328.         ld de,0x6000
  329. ;tile gfx: 256-tiles
  330.         ld hx,0 ;256
  331. recodetiles0
  332.         push hl
  333.         add hl,hl
  334.         add hl,hl
  335.         add hl,hl
  336.         add hl,hl
  337.         ld l,h ;номер тайла
  338.         ld h,tileattr/256
  339.         ld a,(hl) ;_0.._3 номер палитры
  340.         ld hy,a
  341.         pop hl
  342.         call recodetile
  343.         dec hx;bit 6,h ;<0x4000
  344.         jr nz,recodetiles0
  345.         ret
  346.  
  347. recodetile
  348. ;16bytes/tile: 8bytes low bit, 8bytes high bit
  349.         ld lx,8
  350. recodetile0
  351.         ld c,(hl) ;low bits
  352.         set 3,l
  353.         ld b,(hl) ;high bits
  354.         res 3,l
  355.         inc l
  356. ;c=high gfx byte
  357. ;b=low gfx byte
  358. ;hy=_0.._3 номер палитры
  359. ;de=to
  360.         push hl
  361.          ld h,ttilepalrecode/256
  362. recodetilebyte0
  363. ;сдвигом имеем номер цвета a=0..3
  364. ;складываем с номером палитры - получаем левый цвет
  365. ;так же получаем правый цвет
  366. ;пересчитываем в цветовой байт
  367.         call recodetilepixel
  368.         ld (de),a
  369.         inc de
  370.         ld a,e
  371.         and 3
  372.         jr nz,recodetilebyte0
  373.         pop hl
  374.         dec lx
  375.         jr nz,recodetile0
  376.         ld bc,8
  377.         add hl,bc
  378.         ret
  379.  
  380. recodesprite
  381. ;16bytes/tile: 8bytes low bit, 8bytes high bit
  382.         ld lx,8
  383. recodesprite0
  384.         push de
  385.          ld a,d;e
  386.         add a,3*16 ;with mask
  387.          ld d,a;e,a
  388.         ld c,(hl) ;low bits
  389.         set 3,l
  390.         ld b,(hl) ;high bits
  391.         res 3,l
  392.         inc l
  393.         push hl
  394.          ld h,ttilepalrecode/256
  395. recodespritebyte0
  396.         call recodetilepixel
  397.         ld ly,a
  398.         ld a,b
  399.         or c
  400.         rra ;right pixel mask (0=transparent)
  401.         bit 0,a ;left pixel mask (0=transparent)
  402.         ld a,0x00 ;skip all pixels
  403.         jr c,$+4
  404.         ld a,0xb8 ;keep right pixel
  405.         jr nz,$+4
  406.         or 0x47 ;keep left pixel
  407.         ld (de),a ;mask
  408.         ld a,ly
  409.          inc d;e
  410.         ld (de),a ;gfx
  411.          ld a,d;e
  412.         sub 16+1 ;with mask
  413.          ld d,a;e,a
  414.         cpl
  415.         and 3*16 ;with mask
  416.         jr nz,recodespritebyte0
  417.         pop hl
  418.         pop de
  419.          inc d;e
  420.          inc d;e ;next row
  421.         dec lx
  422.         jr nz,recodesprite0
  423.         ;ex de,hl
  424.         ;ld bc,3*16 ;with mask
  425.         ;add hl,bc
  426.         ;ex de,hl
  427.          ld d,0x40
  428.          inc e
  429.         ld bc,8
  430.         add hl,bc
  431.         ret
  432.  
  433. recodetilepixel
  434. ;c=high gfx byte (берём два старших бита и сдвигаем)
  435. ;b=low gfx byte (берём два старших бита и сдвигаем)
  436. ;hy=_0.._3 номер палитры
  437. ;h=ttilepalrecode/256
  438. ;out: a=color byte
  439.         xor a
  440.         rlc c
  441.         rla
  442.         rlc b
  443.         adc a,a ;a=0..3=номер цвета в палитре
  444.          add a,hy
  445.          ld l,a
  446.          ld a,(hl)
  447.         ld ly,a ;%LLLLLlll
  448.         xor a
  449.         rlc c
  450.         rla
  451.         rlc b
  452.         adc a,a ;a=0..3=номер цвета в палитре
  453.          add a,hy
  454.          ld l,a
  455.          ld a,(hl) ;a=%RRRRRrrr
  456.         ;ly=%LLLLLlll
  457.         add a,a
  458.         add a,a
  459.         add a,a
  460.         ;a=%RRrrr000
  461.         xor ly
  462.         and %10111000
  463.         xor ly
  464.         ;a=%RLrrrlll
  465.         ret
  466.  
  467.        
  468. noaddr=0x6000 ;там можно портить 7*40+1 байт
  469. genaddrstack
  470.         call setpgaddrstack4000
  471.         call genaddrstack_onepage
  472.         call setpgaddrstackcopy4000
  473. genaddrstack_onepage
  474. ;для scroll phase 0 стек такой:
  475. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  476. ;(scrR) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  477. ;для scroll phase 1 стек такой:
  478. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  479. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  480. ;для scroll phase 2 стек такой:
  481. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  482. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  483. ;для scroll phase 3 стек такой:
  484. ;(scrR) noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023
  485. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  486.        
  487. ;генерируем один стек на все фазы (строки лежат через 256 байт):
  488. ;noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr, noaddr
  489.         ld h,0x40
  490.         ld de,0x8004
  491.        
  492.         ld b,25
  493. genaddrstack_lines0
  494.         ld l,2 ;2 spare bytes for interrupt
  495.         push bc
  496.         push de
  497.        
  498.         ld bc,noaddr
  499.         ld (hl),c
  500.         inc hl
  501.         ld (hl),b
  502.         inc hl
  503.         ld (hl),c
  504.         inc hl
  505.         ld (hl),b
  506.         inc hl
  507.         ld b,32
  508. genaddrstack_line0
  509.         ld (hl),e
  510.         inc hl
  511.         ld (hl),d
  512.         inc hl
  513.         set 5,d
  514.         ld (hl),e
  515.         inc hl
  516.         ld (hl),d
  517.         inc hl
  518.         res 5,d
  519.         inc de
  520.         djnz genaddrstack_line0
  521.         ld bc,noaddr
  522.         ld (hl),c
  523.         inc hl
  524.         ld (hl),b
  525.         inc hl
  526.         ld (hl),c
  527.         inc hl
  528.         ld (hl),b
  529.         ;inc hl
  530. ;выравнивание на 64*4 = 256
  531.         inc h
  532.        
  533.         pop de
  534.         ex de,hl
  535.         ld bc,40*8
  536.         add hl,bc
  537.         ex de,hl
  538.         pop bc
  539.         djnz genaddrstack_lines0
  540.        
  541.         ret
  542.  
  543. copytilesgfx
  544.         ld de,0x3000+(16*0xec) ;tile 0xec
  545.         ld hl,copytiles_table
  546.         ld b,copytiles_sz
  547. copytilesgfx0
  548.         push bc
  549.         push hl
  550.         ld l,(hl)
  551. ;l=tile from
  552. ;de=addr to
  553.         ld h,3
  554.         add hl,hl
  555.         add hl,hl
  556.         add hl,hl
  557.         add hl,hl ;*16 + 0x3000
  558.         ld bc,16
  559.         ldir
  560.         pop hl
  561.         inc hl
  562.         pop bc
  563.         djnz copytilesgfx0
  564.         ld hl,0x3000+(16*0x26)
  565.         ld de,0x3000+(16*w26)
  566.         ld c,16
  567.         ldir
  568.         ld hl,0x3000+(16*0x91)
  569.         ld de,0x3000+(16*x91)
  570.         ld c,16
  571.         ldir
  572.         ld de,0x3000+(16*x92)
  573.         ld c,16
  574.         ldir
  575.         ret
  576. copytiles_table
  577.         db 0xa0
  578.         db 0xa1
  579.         db 0xa2
  580.         db 0xa3
  581.         db 0x27
  582.         db 0xba
  583.         db 0xbb
  584.         db 0x86
  585.         db 0x87
  586.         db 0x8a
  587.         db 0x8b
  588.         db 0x8e
  589.         db 0x8f
  590.         db 0x25
  591.         db 0x26
  592.         db 0x35
  593.         db 0x36
  594.         db 0x37 ;cloud middle
  595.         db 0x38 ;cloud right
  596. copytiles_sz=$-copytiles_table
  597.        
  598. gentileproc_all
  599.         ld a,(tilepage)
  600.         SETPG16K
  601.         ld de,0x6000 ;data
  602.         call setpgtileprocL
  603.         call gentileproc_all_half
  604.         ld de,0x6001 ;data
  605.         call setpgtileprocR
  606. gentileproc_all_half
  607.         ld hl,0xc000 ;proc
  608. gentileproc_all0
  609.         push hl
  610.         push de
  611.         call gentileproc
  612.         pop de
  613.         ld hl,32
  614.         add hl,de
  615.         ex de,hl
  616.         pop hl
  617.         inc h
  618.         ld a,h
  619.         or 0xc0
  620.         ld h,a
  621.         inc l
  622.         ld a,l
  623.         inc a
  624.         jr nz,gentileproc_all0
  625.         ld (hl),0xf7 ;rst 0x30 for tile #0xff
  626. ;tile for endline = ENDLINETILE;0xff?
  627.         ld hl,(0) ;ok
  628.         ld (oldquitcode),hl
  629.         ld hl,ENDLINETILE*0x0101|0xc000;0xffff
  630.         ld (hl),0xc3 ;"jp"
  631.         ret
  632.  
  633. gentileproc
  634. ;hl=proc
  635. ;de=data
  636. ;out: de=next data
  637. ;генерирует такое:
  638. ;pop hl ;пиксели 0..1
  639. ;dup 7
  640. ;[ld (hl),n]
  641. ;add hl,bc
  642. ;edup
  643. ;[ld (hl),n]
  644. ;pop hl ;пиксели 4..5 в той же странице (другой bit 5 и возможно +1)
  645. ;dup 7
  646. ;[ld (hl),n]
  647. ;add hl,bc
  648. ;edup
  649. ;[ld (hl),n]
  650. ;ld a,(de)
  651. ;inc e
  652. ;ld l,a
  653. ;or 0xc0
  654. ;ld h,a
  655. ;jp (hl)
  656.         push de
  657.         call gentileproc_bytes
  658.         pop de
  659.         inc de
  660.         inc de
  661.         call gentileproc_bytes
  662.         push de
  663.         ex de,hl
  664.         ld hl,gentileproc_jpcode
  665.         ld c,gentileproc_jpcode_sz
  666.         ldir
  667.         if FASTEMPTYTILES
  668.         ld hl,premptytiles_was
  669.         ld de,premptytiles;EMPTYTILE*257+0xc000
  670.         ld c,premptytiles_sz
  671.         ldir
  672.         endif
  673.         pop de
  674.         ret
  675. gentileproc_bytes
  676.         ld (hl),0xe1 ;"pop hl"
  677.         inc hl
  678.         ld (gentileproc_lastnonzeroaddr),hl
  679.        
  680. ;find most popular byte (at least 3 times), change to ld a,n:ld (hl),a
  681. ;это один из первых 6 байтов или 0 (если не найдено)
  682. ;TODO уметь находить две группы по 3 и более
  683.         ld c,0 ;most popular byte (0=not found)
  684.         push de
  685.         push hl
  686.         ex de,hl
  687.         ld e,2 ;max times (find more than that!)
  688.         ld b,7
  689. gentileproc_testpopular_allbytes0
  690.         ld a,(hl)
  691.         push bc
  692.         push hl
  693.         ld d,1 ;times
  694. gentileproc_testpopular0
  695.         inc hl
  696.         inc hl
  697.         inc hl
  698.         inc hl
  699.         cp (hl)
  700.         jr nz,$+3
  701.         inc d ;times
  702.         djnz gentileproc_testpopular0
  703.         pop hl
  704.         pop bc
  705.         ld a,e ;max times
  706.         cp d ;times
  707.         jr nc,gentileproc_testpopular_nomax
  708.         ld e,d ;max times = times
  709.         ld c,(hl) ;most popular byte
  710. gentileproc_testpopular_nomax
  711.         inc hl
  712.         inc hl
  713.         inc hl
  714.         inc hl ;try next byte
  715.         djnz gentileproc_testpopular_allbytes0
  716.         pop hl
  717.         pop de
  718.        
  719.         ld a,c
  720.         or a
  721.         jr z,gentileproc_nooldbyte
  722.         ld (hl),0x3e ;"ld a,n"
  723.         inc hl
  724.         ld (hl),c
  725.         inc hl
  726. gentileproc_nooldbyte
  727.        
  728.         ld b,8
  729. gentileproc_bytes0
  730.         ld a,(de)
  731.         inc de
  732.         inc de
  733.         inc de
  734.         inc de
  735.         or a
  736.         jr z,gentileproc_skipbyte
  737.          cp c
  738.          ld (hl),0x77 ;"ld (hl),a
  739.          jr z,gentileproc_oldbyte
  740.         ld (hl),0x36 ;"ld (hl),n"
  741.         inc hl
  742.         ld (hl),a
  743. gentileproc_oldbyte
  744.         inc hl
  745.         ld (gentileproc_lastnonzeroaddr),hl
  746. gentileproc_skipbyte
  747.         ld (hl),0x09 ;add hl,bc
  748.         inc hl
  749.         djnz gentileproc_bytes0
  750.         ;dec hl ;skip last add
  751. gentileproc_lastnonzeroaddr=$+1
  752.         ld hl,0
  753.         ret
  754.  
  755.         if FASTEMPTYTILES
  756. ;сейчас процедура пустого тайла (0xe424) выглядит так:
  757.         ;pop hl
  758.         ;pop hl ;чтобы был правильный sp
  759.         ;inc e
  760.         ;ld a,(de)
  761.         ;ld l,a
  762.         ;or 0xc0
  763.         ;ld h,a
  764.         ;jp (hl) ;50t
  765. ;оптимизировать последовательность пустых тайлов:
  766. ;1 пустой тайл: проигрыш 54t (проигрыш 35t)
  767. ;2 пустых тайла: проигрыш 26t (выигрыш 23t)
  768. ;3 пустых тайла: выигрыш 0t (выигрыш 31t)
  769. ;>=4 пустых тайла: выигрыш 29..32t/tile
  770. premptytiles_was
  771.         disp EMPTYTILE*257+0xc000
  772. premptytiles
  773. ;-24t
  774.         ld a,l;EMPTYTILE
  775.         ld h,d
  776.         ld l,e ;+12t
  777.         inc l
  778.         cp (hl)
  779.         jr nz,premptytilesq1
  780.         inc l
  781.         cp (hl)
  782.         jr nz,premptytilesq2
  783.         inc l
  784.         cp (hl)
  785.         jr nz,premptytilesq3
  786. premptytiles0
  787.         dup 3
  788.         inc l
  789.         cp (hl)
  790.         jr nz,premptytilesq
  791.         edup
  792.         inc l
  793.         cp (hl)
  794.         jp z,premptytiles0 ;+18..21t/tile
  795. premptytilesq
  796.          ld a,l
  797.          sub e
  798.          ld e,l
  799.          add a,a
  800.          add a,a
  801.          ld l,a
  802.          ld h,0
  803.          add hl,sp
  804.          ld sp,hl ;48t
  805.         ld a,(de)
  806.         ld l,a
  807.         or 0xc0
  808.         ld h,a
  809.         jp (hl)
  810. premptytilesq3
  811.         pop hl
  812.         pop hl
  813.         inc e
  814. premptytilesq2
  815.         pop hl
  816.         pop hl
  817.         inc e
  818. premptytilesq1
  819.         pop hl
  820.         pop hl
  821.         ent
  822. gentileproc_jpcode
  823.         inc e
  824.         ld a,(de)
  825.         ld l,a
  826.         or 0xc0
  827.         ld h,a
  828.         jp (hl)
  829. premptytiles_sz=$-premptytiles_was
  830.         ;display "premptytiles_sz=",premptytiles_sz,"<=0x40!"
  831. gentileproc_jpcode_sz=$-gentileproc_jpcode
  832.         else
  833. gentileproc_jpcode
  834.         inc e
  835.         ld a,(de)
  836.         ld l,a
  837.         or 0xc0
  838.         ld h,a
  839.         jp (hl)
  840. gentileproc_jpcode_sz=$-gentileproc_jpcode
  841.         endif
  842.  
  843.  
  844.         align 256
  845. tileattr
  846.         include "tileattr.asm"
  847. ttilepalrecode
  848.         db 0,1,2,3 ;tilepal0
  849.         db 0,4,5,6 ;tilepal1
  850.         db 0,7,0xf8,0xf9 ;tilepal2
  851.         db 0,0xfa,0xfb,6 ;tilepal3 ;10=тень монеты/каёмка огня, 11=яркая монета/огонь, 12=рубашка Марио (каёмка монеты бывает синяя - для неё берём цвет 6)
  852. ;цвета Марио: [1]=4 (лицо) или 13=0x3131, [2]=14=0xb1b1 (фартук красный, а может быть белый), [3]=12 (рубашка может быть коричневая и зелёная!!!)
  853. ;цвета черепахи/Lakitu: [1]=8 (белый), [2]=2 (зелёный панцирь, а может быть синий!!!) или 15=0xe3e3, [3]=13 (голова черепахи)
  854. ;цвета Goomba/жук/пушка/пуля: [1]=5 (ножка), [2]=6 (чёрный, а может быть тёмно-серый!!!), [3]=4 (шляпа)
  855. ;цвета огня: [1]=8 (белая внутренность), [2]=10 (красный), [3]=11 (жёлтый)
  856. ;цвета гриба: [1]=5 (ножка), [2]=10 (красный), [3]=13 (оранжевый)
  857. ;цветок отличается от черепахи тем, что всегда зелёная ножка
  858. ;платформа отличается от Марио стабильными цветами??? или она ближе к грибу/Goomba наверху
  859. ;наш флаг отличается от черепахи тем, что всегда красная звезда
  860.         db 0,0xfd,0xfe,0xfc ;Mario
  861.         db 0,0xf8,0xff,0xfd ;Koopa/Lakitu
  862.         db 0,5,6,4 ;Goomba/жук/пушка/пуля
  863.         db 0,0xf8,0xfa,0xfb ;огонь
  864.         db 0,5,0xfa,0xfd ;гриб
  865.         db 0,0xf8,2,0xfd ;цветок (всегда зелёная ножка)
  866.         db 0,0xfb,0xf8,0xfa ;монета
  867.         ;db 0,0xfd,0xfa,4 ;платформа
  868.         db 0,5,0xfa,0xfd ;платформа
  869.         db 0,0xf8,0xfa,0xfd ;наш флаг (всегда красная звезда)
  870.  
  871.         ;ds 0x0200-$
  872.        
  873.         if COMPACTDATA
  874. Sprite_Data=$           ;= $0200
  875. Sprite_Y_Position=Sprite_Data     ;db 0;= $0200
  876. ;Sprite data is delayed by one scanline; you must subtract 1 from the sprite's Y coordinate before writing it here. Hide a sprite by writing any values in $EF-$FF here.
  877. ;Sprites are never displayed on the first line of the picture, and it is impossible to place a sprite partially off the top of the screen.
  878. Sprite_Tilenumber=Sprite_Data+1     ;db 0;= $0201
  879. ;For 8x8 sprites, this is the tile number of this sprite within the pattern table selected in bit 3 of PPUCTRL ($2000).
  880. ;For 8x16 sprites, the PPU ignores the pattern table selection and selects a pattern table from bit 0 of this number.
  881. ;76543210
  882. ;||||||||
  883. ;|||||||+- Bank ($0000 or $1000) of tiles
  884. ;+++++++-- Tile number of top of sprite (0 to 254; bottom half gets the next tile)
  885. Sprite_Attributes=Sprite_Data+2     ;db 0;= $0202
  886. ;76543210
  887. ;||||||||
  888. ;||||||++- Palette (4 to 7) of sprite
  889. ;|||+++--- Unimplemented
  890. ;||+------ Priority (0: in front of background; 1: behind background)
  891. ;|+------- Flip sprite horizontally
  892. ;+-------- Flip sprite vertically
  893. Sprite_X_Position=Sprite_Data+3     ;db 0;= $0203
  894. ;X-scroll values of $F9-FF results in parts of the sprite to be past the right edge of the screen, thus invisible. It is not possible to have a sprite partially visible on the left edge.
  895. ;Instead, left-clipping through PPUMASK ($2001) can be used to simulate this effect.
  896.  
  897.         ds 0x0300-$
  898. ;tile buf
  899. VRAM_Buffer1_Offset   db 0;= $0300
  900. VRAM_Buffer1          ds 63;???;= $0301
  901. VRAM_Buffer2_Offset   db 0;= $0340
  902. VRAM_Buffer2          ds 0x100;TitleScreenDataSize-64;63;???;= $0341 ;следующий блок данных в $0363, но нужен буфер до 0x043a (невключительно)
  903.        ds 0x0500-$ ;ClearBuffersDrawIcon чистит 512 байт
  904.        endif
  905.  
  906.        ds 0x0800-$
  907. SCRATCHPAD2=$-0x100
  908.         ds 0x100 ;адреса SCRATCHPAD2+$01xx (сколько???)
  909.  
  910. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  911.         align 256
  912. filepages
  913.         ds 128
  914.  
  915. ;DDp palette: %grbG11RB(low),%grbG11RB(high)
  916. mariopalblack
  917. castlepalette
  918.         dw 0xffff
  919.         dw 0xafaf,0xeded,0x7f7f ;1=средняя труба, 2=яркая труба, 3=каёмка трубы
  920.         dw 0xecec,0x0c0c,0x1f1f ;4=яркий кирпич, 5=блик на кирпиче, 6=дверь замка=тень в кирпичах (по идее чёрные, но на 8-4 тёмно-серые)
  921.         dw 0x3d3d,0x0c0c,0xffff ;7=вода/тень облака, 8=белый, 9=каёмка облака (чёрная)
  922.         dw 0xfdfd,0xadad,0x3f3f ;10=тень монеты, 11=яркая монета, 12=рубашка Марио (каёмка монеты бывает синяя - для неё берём цвет 6)
  923.         dw 0x3d3d,0xbdbd,0xefef ;13=лицо Марио/голова черепахи, 14=фартук Марио, 15=панцирь
  924. undergroundpalette
  925. ;с чёрным фоном:                        каёмка трубы    лицо    фартук  дверь замка, тень в кирпичах (по идее чёрные); рубашка Марио (по идее коричневая), шляпа злого гриба (в подземелье голубая), голова черепахи (по идее оранжевая), стебель кактуса (по идее оранжевый), лицо toad
  926.         ;dw 0xf3f3,0xa3a3,0x6161,0x7373,0xf3f3,0x3131,0xa0a0,0xb3b3
  927.         ;dw 0xf3f3,0x0202,0x0000,0xd3d3,0xf3f3,0xf1f1,0xa1a1,0xb3b3
  928.                                 ;край облака                    разбитый блок с призом, край монеты
  929.         dw 0xffff
  930.         dw 0xafaf,0xeded,0x7f7f ;1=средняя труба, 2=яркая труба, 3=каёмка трубы
  931.         dw 0xeeee,0x4c4c,0x5f5f ;4=яркий кирпич, 5=блик на кирпиче, 6=дверь замка=тень в кирпичах (по идее чёрные, но на 8-4 тёмно-серые)
  932.         dw 0x0e0e,0x0c0c,0xffff ;7=вода/тень облака, 8=белый, 9=каёмка облака (чёрная)
  933.         dw 0xfdfd,0xadad,0x3f3f ;10=тень монеты, 11=яркая монета, 12=рубашка Марио (каёмка монеты бывает синяя - для неё берём цвет 6)
  934.         dw 0x3d3d,0xbdbd,0xefef ;13=лицо Марио/голова черепахи, 14=фартук Марио, 15=панцирь
  935. waterpalette
  936.         dw 0xcccc ;небо
  937.         dw 0xafaf,0xeded,0x7f7f ;1=средняя труба, 2=яркая труба, 3=каёмка трубы
  938.         dw 0x6f6f,0x6c6c,0xffff ;4=яркий кирпич, 5=блик на кирпиче, 6=дверь замка=тень в кирпичах (по идее чёрные, но на 8-4 тёмно-серые)
  939.         dw 0x0e0e,0x0c0c,0xffff ;7=вода/тень облака, 8=белый/коралл???/подводная монета???, 9=каёмка облака (чёрная)
  940.         dw 0xfdfd,0xadad,0x3f3f ;10=тень монеты, 11=яркая монета, 12=рубашка Марио (каёмка монеты бывает синяя - для неё берём цвет 6)
  941.         dw 0x3d3d,0xbdbd,0xecec ;13=лицо Марио/голова черепахи, 14=фартук Марио, 15=панцирь/серая рыбка
  942. mariopal
  943. groundpalette
  944. ;с синим небом:
  945.                           ;23           ;e3           ;e0
  946.         ;dw 0xc0c0,0xa3a3,0x6161,0x7373,0xc0c0,0x3131,0xa0a0,0xb3b3
  947.         ;dw 0xc0c0,0x0202,0x0000,0xd3d3,0xc0c0,0xf1f1,0xa1a1,0xb3b3
  948.                 ;вода/кусок облака
  949.         dw 0xcccc ;небо
  950.         dw 0xafaf,0xeded,0x7f7f ;1=средняя труба (0xe3 слишком холодно), 2=яркая труба (0x61 слишком ярко), 3=каёмка трубы
  951.         dw 0x7d7d,0xacac,0xffff ;4=яркий кирпич (0x11 слишком ярко, 0x31 слишком насыщенно, 0x71 слишком коричнево - но в VirtualNES так), 5=блик на кирпиче, 6=дверь замка=тень в кирпичах (по идее чёрные, но на 8-4 тёмно-серые)
  952.         dw 0x0e0e,0x0c0c,0xffff ;7=вода/тень облака, 8=белый, 9=каёмка облака (чёрная)
  953.         dw 0xfdfd,0xadad,0x3f3f ;10=тень монеты/каёмка огня, 11=яркая монета/огонь, 12=рубашка Марио (0xb3 слишком насыщенно, каёмка монеты бывает синяя - для неё берём цвет 6)
  954.         dw 0x3d3d,0xbdbd,0xefef ;13=лицо Марио/голова черепахи, 14=фартук Марио, 15=панцирь
  955.  
  956. ;цвета Марио: [1]=4 (лицо) или 13=0x3131, [2]=14=0xb1b1 (фартук красный, а может быть белый), [3]=12 (рубашка может быть коричневая и зелёная!!!)
  957. ;цвета черепахи/Lakitu: [1]=8 (белый), [2]=2 (зелёный панцирь, а может быть синий!!!) или 15=0xe3e3, [3]=13 (голова черепахи)
  958. ;цвета Goomba/жук/пушка/пуля: [1]=5 (ножка), [2]=6 (чёрный, а может быть тёмно-серый!!!), [3]=4 (шляпа)
  959. ;цвета огня: [1]=8 (белая внутренность), [2]=10 (красный), [3]=11 (жёлтый)
  960. ;цвета рыбы: [1]=8 (белое брюшко), [2]=15 (серый), [3]=13 (розовый хвост) - как у черепахи
  961. ;цвета гриба: [1]=5 (ножка), [2]=10 (красный), [3]=13 (ярко-оранжевый)
  962.  
  963. quit
  964.         call swapimer
  965.         call shutay
  966. oldquitcode=$+1
  967.         ld hl,0
  968.         ld (0),hl
  969. quitquit
  970.         halt
  971.         GET_KEY ;вычитать Break
  972.         QUIT
  973.  
  974. noloadgfx
  975.         ld e,6
  976.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  977.         ld e,0
  978.         OS_SETSCREEN
  979.         ld e,0 ;color byte
  980.         OS_CLS
  981.         ld hl,tnofile
  982. prerr0
  983.         ld a,(hl)
  984.         or a
  985.         jr z,quitquit
  986.         inc hl
  987.         push hl
  988.         PRCHAR
  989.         pop hl
  990.         jr prerr0
  991.  
  992. swapimer
  993.         di
  994.          if MULTITASKING
  995.          ld hl,(0x0038+3) ;адрес intjp
  996.          ld (intjpaddr),hl
  997.          endif
  998.         ld de,0x0038
  999.         ld hl,oldimer
  1000.         ld bc,3
  1001. swapimer0
  1002.         ld a,(de)
  1003.         ldi ;[oldimer] -> [0x0038]
  1004.         dec hl
  1005.         ld (hl),a ;[0x0038] -> [oldimer]
  1006.         inc hl
  1007.         jp pe,swapimer0
  1008.         ;jr $
  1009.         ei
  1010.         ret
  1011. oldimer
  1012.         jp on_int ;заменится на код из 0x0038
  1013.  
  1014.        
  1015. setpgs_code
  1016. codepage4000=$+1
  1017.         ld a,0
  1018.          if RESTOREPG16K
  1019.          ;ld (curpg4000),a
  1020.          endif
  1021.         SETPG16K
  1022. codepage8000=$+1
  1023.         ld a,0
  1024.         SETPG32KLOW
  1025. codepagec000=$+1
  1026.         ld a,0
  1027.         SETPG32KHIGH
  1028.         ret
  1029.        
  1030. setpgs_scr
  1031. tilepage=$+1
  1032.         ld a,0
  1033.          if RESTOREPG16K
  1034.          ;ld (curpg4000),a
  1035.          endif
  1036.         SETPG16K
  1037. ;setpgs_scr_low=$+1
  1038. ;        ld a,0;pgscr0_0 ;scr0_0
  1039.         call getuser_scr_low
  1040.         SETPG32KLOW
  1041. ;setpgs_scr_high=$+1
  1042. ;        ld a,0;pgscr0_1 ;scr0_1
  1043.         call getuser_scr_high
  1044.         SETPG32KHIGH
  1045.         ret
  1046.  
  1047. getuser_scr_low
  1048. getuser_scr_low_patch=$+1
  1049. getuser_scr_low_patchN=0xff&(user_scr0_low^user_scr1_low)
  1050.         ld a,(user_scr0_low) ;ok
  1051.         ret
  1052.  
  1053. getuser_scr_high
  1054. getuser_scr_high_patch=$+1
  1055. getuser_scr_high_patchN=0xff&(user_scr0_high^user_scr1_high)
  1056.         ld a,(user_scr0_high) ;ok
  1057.         ret
  1058.  
  1059.  
  1060.         align 256
  1061. tytoscr
  1062.         dup 200
  1063.         db (($&0xff)*40)&0xff
  1064.         edup
  1065.         align 256
  1066.         dup 200
  1067.         db (($&0xff)*40)/256 + 0x80
  1068.         edup
  1069.  
  1070.         macro NEXTCOLUMN
  1071.         bit 6,h
  1072.         set 6,h
  1073.         jr z,$+2+4+2+2+1
  1074.         ld a,h
  1075.         xor 0x60
  1076.         ld h,a
  1077.         and 0x20
  1078.         jr nz,$+3
  1079.         inc hl
  1080.         endm
  1081.  
  1082.         macro COUNTSCRADDR
  1083.         add a,(hl)
  1084.         inc h
  1085.          ld c,a
  1086.         ;ld h,(hl)
  1087.          adc a,(hl)
  1088.          sub c
  1089.        ld l,c;a
  1090.        ;ld a,b
  1091.        ;adc a,h
  1092.         ;inc h
  1093.         ;ld l,c ;x
  1094.         ;add a,(hl) ;8+7=15t, а если rra:srl a=12t, плюс выигрываем 2 команды bit
  1095.          ;inc h
  1096.          ;ld a,(hl)
  1097.          ;ld (prcharxy_jr),a ;4+7+13+12(jr) = 35t, а если bit:jr z:bit:jr z, то в среднем 16+7+12=35t тоже
  1098.         endm
  1099.  
  1100.         macro NEXTCOLUMNS0
  1101.         ld h,a ;.00
  1102.         push hl
  1103.         set 6,h ;.10
  1104.         push hl
  1105.         xor 0x20
  1106.         ld h,a ;.01
  1107.         push hl
  1108.         set 6,h ;.11
  1109.         endm
  1110.         macro NEXTCOLUMNS1
  1111.         ld c,a
  1112.         xor 0x40
  1113.         ld h,a ;.10
  1114.         push hl
  1115.         xor 0x60
  1116.         ld h,a ;.01
  1117.         push hl
  1118.         set 6,h ;.11
  1119.         push hl
  1120.         ld h,c ;.00
  1121.         inc hl
  1122.         endm
  1123.         macro NEXTCOLUMNS2
  1124.         ld h,a
  1125.         set 5,h ;.01
  1126.         push hl
  1127.         set 6,h ;.11
  1128.         push hl
  1129.         ld h,a ;.00
  1130.         inc hl
  1131.         push hl
  1132.         set 6,h ;.10
  1133.         endm
  1134.         macro NEXTCOLUMNS3
  1135.         ld c,a
  1136.         xor 0x60
  1137.         ld h,a ;.11
  1138.         push hl
  1139.         ld h,c ;.00
  1140.         inc hl
  1141.         push hl
  1142.         set 6,h ;.10
  1143.         push hl
  1144.          ld a,h ;нельзя старое, т.к. было inc hl
  1145.          xor 0x60
  1146.          ld h,a ;.01
  1147.         endm
  1148.  
  1149. prcharxy
  1150. ;de=gfx
  1151. ;la=yx
  1152. ;CY=0
  1153.         ld h,tytoscr/256
  1154.        rra
  1155.        jr c,prcharxy_nextcolumns13
  1156.        rra;srl a
  1157.        jr c,prcharxy_nextcolumns2
  1158. prcharxy_nextcolumns0
  1159.         COUNTSCRADDR
  1160.         NEXTCOLUMNS0
  1161.         jp prcharxy_scrok
  1162. prcharxy_nextcolumns2
  1163.         COUNTSCRADDR
  1164.         NEXTCOLUMNS2
  1165.         jp prcharxy_scrok
  1166. prcharxy_nextcolumns13
  1167.        srl a
  1168.        jr c,prcharxy_nextcolumns3
  1169. prcharxy_nextcolumns1
  1170.         COUNTSCRADDR
  1171.         NEXTCOLUMNS1
  1172.         jp prcharxy_scrok
  1173. prcharxy_nextcolumns3
  1174.         COUNTSCRADDR
  1175.         NEXTCOLUMNS3
  1176. prcharxy_scrok
  1177.  
  1178.         macro SHOWBYTEBEHIND
  1179.          inc d;e
  1180.         cp (hl) ;scr
  1181.         jr nz,$+5
  1182.         ld a,(de)
  1183.         ld (hl),a ;scr
  1184.         xor a
  1185.          inc d;e
  1186.         endm
  1187.         macro SHOWBYTEBEHIND_LAST
  1188.         cp (hl) ;scr
  1189.         ret nz
  1190.          inc d;e
  1191.         ld a,(de)
  1192.         ld (hl),a ;scr
  1193.         ret
  1194.         endm
  1195.        
  1196.         macro SHOWBYTE ;TODO pop de
  1197.         ex de,hl
  1198.         ld a,(de) ;scr
  1199.         and (hl) ;font
  1200.          inc h;l
  1201.         or (hl)
  1202.          inc h;l
  1203.         ld (de),a ;scr
  1204.         ex de,hl
  1205.         endm
  1206.         macro SHOWBYTE_LAST ;TODO pop de
  1207.         ex de,hl
  1208.         ld a,(de) ;scr
  1209.         and (hl) ;font
  1210.          inc h;l
  1211.         or (hl)
  1212.         ld (de),a ;scr
  1213.         ret
  1214.         endm
  1215.        
  1216.         ;ld a,(de) ;font
  1217.         ;ld (hl),a ;scr
  1218.         ; inc d;e
  1219.         ;add hl,bc
  1220.        
  1221.        
  1222. ;x=???432Xx
  1223. ;scraddr = %1xX????? ?????432
  1224.         ld bc,40 ;TODO в зависимости от переворота
  1225.        
  1226.         bit 5,(ix+2) ;attributes.behind
  1227.         jp nz,prcharxy_behind
  1228.        
  1229.         dup 7
  1230.         SHOWBYTE
  1231.         add hl,bc
  1232.         edup
  1233.         SHOWBYTE
  1234.        
  1235.         pop hl
  1236.         dup 7
  1237.         SHOWBYTE
  1238.         add hl,bc
  1239.         edup
  1240.         SHOWBYTE
  1241.        
  1242.         pop hl
  1243.         dup 7
  1244.         SHOWBYTE
  1245.         add hl,bc
  1246.         edup
  1247.         SHOWBYTE
  1248.        
  1249.         pop hl
  1250.         dup 7
  1251.         SHOWBYTE
  1252.         add hl,bc
  1253.         edup
  1254.         SHOWBYTE_LAST
  1255.         ;ret ;там уже есть
  1256.  
  1257. prcharxy_behind
  1258.         xor a
  1259.         dup 7
  1260.         SHOWBYTEBEHIND
  1261.         add hl,bc
  1262.         edup
  1263.         SHOWBYTEBEHIND
  1264.        
  1265.         pop hl
  1266.         dup 7
  1267.         SHOWBYTEBEHIND
  1268.         add hl,bc
  1269.         edup
  1270.         SHOWBYTEBEHIND
  1271.        
  1272.         pop hl
  1273.         dup 7
  1274.         SHOWBYTEBEHIND
  1275.         add hl,bc
  1276.         edup
  1277.         SHOWBYTEBEHIND
  1278.        
  1279.         pop hl
  1280.         dup 7
  1281.         SHOWBYTEBEHIND
  1282.         add hl,bc
  1283.         edup
  1284.         SHOWBYTEBEHIND_LAST
  1285.         ;ret ;там уже есть
  1286.  
  1287. EmulatePPU
  1288.         if FASTDEMOBEFOREBREAKPOINT
  1289.         ld a,0
  1290.         sub 4
  1291.         ld ($-1-2),a
  1292.          ;scf
  1293.         jr c,EmulatePPU_noskipgo
  1294. skipPPU=$
  1295.         ret
  1296. EmulatePPU_noskipgo    
  1297.         endif
  1298. ;ждать флаг ожидания готовности экрана (включается по прерыванию)
  1299. ;иначе будет так:
  1300. ;фрейм 1:
  1301. ;видим экран0, рисуем экран1
  1302. ;фрейм 2:
  1303. ;видим экран0, закончили рисовать экран1, [вот тут нужно ожидание], начали рисовать экран0 (хотя его видим)
  1304. ;фрейм 3:
  1305. ;видим экран1
  1306. ;готовность - это когда текущий таймер != таймер конца прошлой отрисовки
  1307. ;проверяем оба таймера, а то могло случиться системное прерывание
  1308. EmulatePPU_waitforscreenready0
  1309.         call gettimer
  1310. endoflastredrawtimer=$+1
  1311.         ld de,0
  1312.         or a
  1313.         sbc hl,de
  1314.         jr z,EmulatePPU_waitforscreenready0
  1315.  
  1316.         if OSCALLS
  1317. curpalette=$+1
  1318.         ld de,mariopal
  1319. oldpalette=$+1
  1320.         ld hl,0
  1321.         ld (oldpalette),de
  1322.         or a
  1323.         sbc hl,de
  1324.         jp z,EmulatePPU_nochpal ;реально поддержано изменение цвета Марио в палитре: при этом пишется oldpalette=левоечисло
  1325.         push de
  1326.         ;OS_GETTIMER ;hlde=timer
  1327.         ;ld (oldtimer),de ;иначе yield вылетит без ожидания прерывания
  1328.         YIELD ;иначе можем напороться на di в swapimer
  1329.         call swapimer ;делать это после YIELD, т.к. внутри di..ei
  1330.         pop de
  1331.         OS_SETPAL ;на это время восстановлен обработчик прерываний, музыка выключена (а так надо посчитать, сколько прошло прерываний по системному таймеру и добавить в игровой таймер)
  1332.         YIELD ;иначе палитра не установится
  1333.         call swapimer
  1334.         else
  1335. EmulatePPU_nochpal
  1336.         endif
  1337.  
  1338.         call setpgs_scr
  1339.        
  1340. wascurkeyredraw=$+1
  1341.         ld a,0
  1342.         cp key_redraw
  1343.         if 1==1
  1344.         jr nz,EmulatePPU_nofullcls
  1345.         xor a
  1346.         ld (wascurkeyredraw),a
  1347.         ;ld hl,0x8000
  1348.         ;ld de,0x8000+1
  1349.         ;ld bc,0x7fff
  1350.         ;ld (hl),l;0
  1351.         ;ldir
  1352.         ld e,0
  1353.         OS_SETSCREEN
  1354.         ld e,0 ;color byte
  1355.         OS_CLS
  1356.         ld e,1
  1357.         OS_SETSCREEN
  1358.         ld e,0 ;color byte
  1359.         OS_CLS
  1360. EmulatePPU_nofullcls
  1361.         endif
  1362.         ld hl,0x8000+4+32
  1363.         call emppucls
  1364.         ld hl,0xa000+4+32
  1365.         call emppucls
  1366.         ld hl,0xc000+4+32
  1367.         call emppucls
  1368.         ld hl,0xe000+4+32
  1369.         call emppucls ;cls=173000
  1370.        
  1371.         ld hl,proc_endline
  1372.         ld (0),hl ;иначе системный обработчик прерываний успевает запортить (0x0001)
  1373.         call prtilesfast ;143700
  1374.  
  1375.         call setpgs_scr
  1376.         ;ld a,0x40
  1377.         ;ld (fonthsb),a
  1378. ;рисуем спрайты в обратном порядке (0-й на переднем плане)
  1379.         ld ix,Sprite_Data+256-4
  1380.         ;ld b,64;8
  1381. prsprites0
  1382.         ;push bc
  1383.         ld a,(ix) ;y
  1384.          sub 8*YSKIPFROMTOP
  1385.         cp 200-8
  1386.         jp nc,prsprites_skip ;большинство спрайтовых записей пустые, можно даже проверять на ==0xf8
  1387.         ld l,a ;y
  1388.  
  1389.         ld a,(ix+2) ;attributes
  1390.         rla ;flip vertically ;TODO программно
  1391. spritepage=$+1
  1392. spritepagemirhor=$+2
  1393.         ld bc,0
  1394.         jr nc,$+5
  1395. spritepagemirver=$+1
  1396. spritepagemirhorver=$+2
  1397.         ld bc,0
  1398.         rla ;flip horizontally
  1399.         ld a,c;
  1400.         jr nc,$+3
  1401.         ld a,b;mirver
  1402.          if RESTOREPG16K
  1403.          ;ld (curpg4000),a
  1404.          endif
  1405.         SETPG16K
  1406.        
  1407.         ld a,(ix+3) ;x
  1408.          inc a
  1409.          jr z,prsprites_skip ;почему-то прыжки на левой границе экрана в контакте с камнем дают x=0xff TODO
  1410.         srl a
  1411.         add a,4*4
  1412.        
  1413.         ld e,(ix+1) ;tile
  1414.         ld d,0x40 ;gfx
  1415.         ;ld l,e
  1416.         ;ld h,0x40/64
  1417.         ; add hl,hl
  1418.         ; add hl,hl
  1419.         ; add hl,hl
  1420.         ; add hl,hl
  1421.         ; add hl,hl
  1422.         ; add hl,hl
  1423.         ;ex de,hl
  1424. ;la=yx
  1425. ;de=gfx
  1426.         call prcharxy
  1427. prsprites_skip
  1428.         ;ld bc,-4
  1429.         ;add ix,bc
  1430.         ;pop bc
  1431.         ;djnz prsprites0
  1432.         ld a,lx
  1433.         sub 4
  1434.         ld lx,a
  1435.         jp nz,prsprites0 ;0-й спрайт - край монетки, можно не выводить
  1436.         ;jp nc,prsprites0
  1437.  
  1438.         ld a,1
  1439. curscreen=$+1
  1440.         xor 1
  1441.         ld (curscreen),a
  1442.         if OSCALLS
  1443.         ld e,a
  1444.         OS_SETSCREEN ;фактически включится по прерыванию ;первый отобразится 0-й экран
  1445.          ld a,e
  1446.         endif
  1447.          add a,a
  1448.          add a,a
  1449.          add a,a
  1450.          ld (imer_curscreen_value),a
  1451.          ;ld bc,0x7ffd
  1452.          ;out (c),a
  1453.  
  1454.         call gettimer
  1455.         ld (endoflastredrawtimer),hl
  1456.  
  1457. ;        ld hl,setpgs_scr_low
  1458. ;        ld a,(hl)
  1459. ;setpgs_scr_low_xor=$+1
  1460. ;        xor 2
  1461. ;        ld (hl),a
  1462. ;        ld hl,setpgs_scr_high
  1463. ;        ld a,(hl)
  1464. ;setpgs_scr_high_xor=$+1
  1465. ;        xor 2
  1466. ;        ld (hl),a
  1467.         ld hl,getuser_scr_low_patch
  1468.         ld a,(hl)
  1469.         xor getuser_scr_low_patchN
  1470.         ld (hl),a
  1471.         ld hl,getuser_scr_high_patch
  1472.         ld a,(hl)
  1473.         xor getuser_scr_high_patchN
  1474.         ld (hl),a
  1475.  
  1476.         call setpgs_code
  1477.         ld d,0
  1478.         ld b,d
  1479.         ret        
  1480.  
  1481. emppucls
  1482.         ld (emppuclssp),sp
  1483.         ld de,0
  1484.         ld bc,40
  1485.         ld a,200
  1486. emppucls0
  1487.         ld sp,hl ;во время прерывания de=0
  1488.         ld (hl),e
  1489.         dup 32/2
  1490.         push de
  1491.         edup
  1492.         add hl,bc
  1493.         dec a
  1494.         jr nz,emppucls0
  1495. emppuclssp=$+1
  1496.         ld sp,0
  1497.         ret
  1498.  
  1499.         include "nesconst.asm"
  1500.         include "smbconst.asm"
  1501.        
  1502. TitleScreen
  1503.         ds TitleScreenDataSize
  1504.  
  1505. prtilesfast
  1506.         call setpgaddrstack4000
  1507.         ld hl,0x2000 + (32*YSKIPFROMTOP)
  1508.         ld de,0x4000+6 ;addrstack
  1509.         ld bc,0x0280;0x0220
  1510.         call prtilesfast0block
  1511.        
  1512.          ld a,(Sprite0HitDetectFlag)
  1513.          or a
  1514.          ld c,0x80
  1515.          jr z,prtilesfastbottom ;no scroll
  1516.        
  1517.         ld a,(PPU_CTRL_REG1)
  1518.         rra
  1519.         jr nc,$+4
  1520.         set 2,h ;2nd tilemap
  1521.  
  1522.         ld a,(PPU_SCROLL_REG_H)
  1523.         rra
  1524.         ;rra
  1525.         ;rra
  1526.         and 127;31
  1527.         ld c,a ;scroll
  1528.         push hl
  1529.          srl a
  1530.          srl a
  1531.         add a,l
  1532.         ld l,a
  1533. ;будем выводить слева 32-scroll, справа scroll знакомест
  1534.        
  1535.         push bc
  1536.         push de ;screen (addrstack)
  1537.          ld a,c
  1538.          and 3
  1539.          jr z,prtilesfast_noblankleft
  1540.          dec de
  1541.          dec a
  1542.          jr nz,$-3
  1543. prtilesfast_noblankleft
  1544.         ld a,128;32
  1545.         sub c
  1546.         ld c,a
  1547.         ld b,25-2
  1548.         call prtilesfast0block
  1549.         pop de ;screen (addrstack)
  1550.         pop bc ;scroll
  1551.         pop hl
  1552.         ld a,h
  1553.         xor 4
  1554.         ld h,a ;another tilemap
  1555.         ;ld b,0
  1556.         ld a,128;32
  1557.         sub c
  1558.          ;add a,a
  1559.          ;add a,a
  1560.         add a,e
  1561.         ld e,a
  1562.         ;adc a,d
  1563.         ;sub e
  1564.         ;ld d,a
  1565.  
  1566. prtilesfastbottom
  1567.         ld b,25-2
  1568.         ld a,c
  1569.         or a
  1570.         ret z
  1571.        
  1572. ;для scroll phase 0 стек такой:
  1573. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1574. ;(scrR) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1575. ;для scroll phase 1 стек такой:
  1576. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1577. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1578. ;для scroll phase 2 стек такой:
  1579. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1580. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1581. ;для scroll phase 3 стек такой:
  1582. ;(scrR) noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023
  1583. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1584.        
  1585. ;генерируем один стек на все фазы (строки лежат через 256 байт):
  1586. ;noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr, noaddr
  1587. prtilesfast0block
  1588.         bit 0,e
  1589.         jr z,prtilesfast0block_even
  1590.          res 0,e
  1591.         push bc
  1592.         push de
  1593.         push hl
  1594.         push bc
  1595.         ;ld a,(setpgs_scr_high)
  1596.         call getuser_scr_high
  1597.         SETPG32KLOW
  1598.         call setpgtileprocL
  1599.         pop bc
  1600.         call prtilesfast0lines
  1601.         ;ld a,(setpgs_scr_low)
  1602.         call getuser_scr_low
  1603.         SETPG32KLOW
  1604.         call setpgtileprocR
  1605.         pop hl
  1606.         pop de
  1607.         pop bc
  1608.          inc de
  1609.          inc de
  1610.         jp prtilesfast0lines
  1611.  
  1612. prtilesfast0block_even
  1613.         push bc
  1614.         push de
  1615.         push hl
  1616.         push bc
  1617.         ;ld a,(setpgs_scr_low)
  1618.         call getuser_scr_low
  1619.         SETPG32KLOW
  1620.         call setpgtileprocL
  1621.         pop bc
  1622.         call prtilesfast0lines
  1623.         ;ld a,(setpgs_scr_high)
  1624.         call getuser_scr_high
  1625.         SETPG32KLOW
  1626.         call setpgtileprocR
  1627.         pop hl
  1628.         pop de
  1629.         pop bc
  1630.         ;call prtilesfast0
  1631.         ;ret
  1632.        
  1633. ;hl=tileaddr for line start
  1634. ;de=addrstack
  1635. ;b=hgt
  1636. ;c=width ;max 128
  1637. ;out: hl=tileaddr after last line, de=addrstack after last line
  1638. prtilesfast0lines
  1639.         ld hy,d
  1640.         ld ly,e ;iy=addrstack
  1641.         ld (prtilelinefast_sp),sp
  1642.         dec c
  1643.         srl c
  1644.         srl c
  1645.         inc c ;c=((width+3)/4)
  1646.         ld a,l
  1647.         add a,c ;без переноса, т.к. читаем тайлы через inc e
  1648.         ld l,a ;hl=tileaddr for line end
  1649. ;hl=tileaddr for line end
  1650. ;iy=addrstack
  1651. ;b=hgt
  1652. ;c=((width+3)/4)
  1653.         exx
  1654.         ld bc,40
  1655.         exx
  1656.         ld e,32
  1657. ;a=l
  1658.         ;jr $
  1659. _prtilesfast0
  1660.         ld sp,iy ;addrstack for this line
  1661.         inc hy ;addrstack for next line
  1662.         sub c ;без переноса, т.к. читаем тайлы через inc e
  1663.         ld d,(hl) ;old tile after last tile
  1664.         ld (hl),ENDLINETILE;0xfe ;patch after last tile
  1665.         exx
  1666.         ld e,a
  1667.         exx
  1668.         ld a,h
  1669.         exx
  1670.         ld d,a ;de=tileaddr for line start
  1671.         ld a,(de)
  1672.           ;inc e
  1673.         ld l,a
  1674.         or 0xc0
  1675.         ld h,a
  1676.         jp (hl)
  1677. proc_endline
  1678.         exx
  1679.         ld (hl),d ;unpatch after last tile
  1680.         ;add hl,de ;+32 (for next tileline) ;это надо делать для адреса начала строки, а адрес конца строки перекошен по HSB
  1681.          ld a,l
  1682.          sub c
  1683.          add a,e
  1684.          jp nc,$+4
  1685.          inc h
  1686.          add a,c
  1687.          ld l,a
  1688.         djnz _prtilesfast0
  1689. prtilelinefast_sp=$+1
  1690.         ld sp,0
  1691.         ld d,hy
  1692.         ld e,ly
  1693.         sub c ;без переноса, т.к. читаем тайлы через inc e
  1694.         ld l,a ;hl=tileaddr after last line
  1695.         ret
  1696.        
  1697. setpgaddrstack4000
  1698. pgaddrstack=$+1
  1699.         ld a,0
  1700.          if RESTOREPG16K
  1701.          ;ld (curpg4000),a
  1702.          endif
  1703.         SETPG16K
  1704.         ret
  1705. setpgaddrstackcopy4000 ;только в ините и int
  1706. pgaddrstackcopy=$+1
  1707.         ld a,0
  1708.         SETPG16K
  1709.         ret
  1710.  
  1711. setpgtileprocL
  1712. pgtileprocL=$+1
  1713.         ld a,0
  1714.         SETPG32KHIGH
  1715.         ret
  1716. setpgtileprocR
  1717. pgtileprocR=$+1
  1718.         ld a,0
  1719.         SETPG32KHIGH
  1720.         ret
  1721.  
  1722. shutay
  1723.         ld de,0xe00
  1724. shutay0
  1725.         dec d
  1726.         ld bc,0xfffd
  1727.         out (c),d
  1728.         ld b,0xbf
  1729.         out (c),e
  1730.         jr nz,shutay0
  1731.         ret
  1732.        
  1733.         if OSCALLS==0
  1734. oldpalette=$
  1735.         dw 0
  1736.         endif
  1737. on_int
  1738. ;if stack in 0x4000..0x7fff:
  1739. ;restore stack from pgaddrstackcopy (set in 0x4000 temporarily, then set pgaddrstack)
  1740. ;else restore stack with de;0
  1741.         ld (on_int_hl),hl
  1742.         ld (on_int_sp),sp
  1743.         ld (on_int_spcopy),sp
  1744.         pop hl
  1745.         ld (on_int_sp2),sp
  1746.         ld (on_int_jp),hl
  1747.        
  1748.         ld sp,INTSTACK
  1749.        
  1750.         push af
  1751.         push bc
  1752.         push de
  1753.  
  1754.         if RESTOREPG16K
  1755.         ld a,(CURPG16K) ;ok
  1756.         push af
  1757.         endif
  1758.        
  1759. imer_curscreen_value=$+1
  1760.          ld a,0
  1761.          ld bc,0x7ffd
  1762.          out (c),a
  1763.  
  1764.         ld a,(on_int_sp+1)
  1765.         sub 0x40
  1766.         cp 0x3f ;запас, чтобы не захватить очистку экрана в 0x8000
  1767.         ex de,hl;ld hl,0
  1768.         jr nc,on_int_norestoredata
  1769.         ;jr $
  1770.         ld a,(pgaddrstackcopy)
  1771.         SETPG16K
  1772. on_int_spcopy=$+1
  1773.         ld hl,(0) ;ok
  1774.         ;if RESTOREPG16K==0
  1775.         ld a,(pgaddrstack)
  1776.         SETPG16K
  1777.         ;endif
  1778. on_int_norestoredata
  1779. on_int_sp=$+1
  1780.         ld (0),hl ;восстановили запоротый стек
  1781.  
  1782.         if MULTITASKING
  1783.         ld hl,on_int_q
  1784. intjpaddr=$+1
  1785.         ld (0),hl
  1786.         push ix
  1787.         push iy
  1788.         ex af,af'
  1789.        exx
  1790.        push af
  1791.        push bc
  1792.        push de
  1793.        push hl
  1794.        ld a,(curscreen)
  1795.        ld e,a
  1796.        OS_SETSCREEN ;вызываем здесь, а не в рандомном месте, иначе даже с одной задачей можем получить непредсказуемую задержку, которую не фиксирует наш таймер? с несколькими задачами надо учитывать и системный - TODO
  1797. curpalette=$+1
  1798.        ld de,mariopal
  1799.        OS_SETPAL
  1800.        
  1801.        GET_KEY
  1802.        cp key_redraw
  1803.        jr nz,$+5
  1804.        ld (wascurkeyredraw),a ;иначе не пишем
  1805.  
  1806.        pop hl
  1807.        pop de
  1808.        pop bc
  1809.        pop af
  1810.        exx
  1811.        ex af,af'
  1812.         pop iy
  1813.         pop ix
  1814.         endif
  1815.        
  1816.         if MULTITASKING==0 ;OSCALLS==0
  1817. curpalette=$+1
  1818.         ld de,mariopal
  1819.         ld hl,31
  1820.         add hl,de
  1821.         ld c,0xff
  1822.         ld a,7
  1823.         dup 8
  1824.         OUT (0xF6),A
  1825.         ld d,(hl)
  1826.         dec hl
  1827.         ld b,(hl) ;DDp palette low bits
  1828.         OUT (c),d;(0xFF),A
  1829.         dec hl
  1830.         dec a
  1831.         edup
  1832.         ld a,7
  1833.         dup 7
  1834.         OUT (0xFE),A
  1835.         ld d,(hl)
  1836.         dec hl
  1837.         ld b,(hl) ;DDp palette low bits
  1838.         OUT (c),d;(0xFF),A
  1839.         dec hl
  1840.         dec a
  1841.         edup
  1842.         OUT (0xFE),A ;0
  1843.         ld d,(hl)
  1844.         dec hl
  1845.         ld b,(hl) ;DDp palette low bits
  1846.         OUT (c),d;(0xFF),A
  1847.         endif
  1848.  
  1849.         ld hl,(curtimer)
  1850.         inc hl
  1851.         ld (curtimer),hl
  1852.  
  1853.         if MUSIC
  1854.         if MUSICONINT
  1855.         ld a,(codepage4000)
  1856.         SETPG16K
  1857.         ld b,0
  1858.         ld d,b
  1859. soundenginecall=$
  1860.         call SoundEngine
  1861.         endif
  1862.  
  1863.         ld c,0xfd
  1864.  
  1865.         if SWEEP
  1866. ;$4001(sq1)/$4005(sq2) bits
  1867. ;--------------------------
  1868. ;0-2    right shift amount
  1869. ;3      decrease / increase (1/0) wavelength
  1870. ;4-6    sweep update rate ;frequency at which $4002/3 is updated with the new calculated wavelength. The refresh rate frequency is 120Hz/(N+1), where N is the value written
  1871. ;7      sweep enable
  1872. sweep1=$+1
  1873.         ld de,0 ;сколько бит в этом счётчике??? будем считать, что 8
  1874.         ld a,(SND_SQUARE1_REG+1)
  1875.         rra
  1876.         rra
  1877.         rra
  1878.         rra
  1879.         and 7 ;sweep rate
  1880.         inc a
  1881.         ld b,a
  1882. sweep1counter=$+1
  1883.         ld a,0
  1884.         sub 2 ;2 "sound frames"
  1885.         jr nc,$+3
  1886.         add a,b ;sweep rate
  1887.         ld (sweep1counter),a
  1888.         jr nc,sweep1noinc
  1889.         inc e
  1890.         ld (sweep1),de
  1891. sweep1noinc
  1892.         ld a,(SND_SQUARE1_REG+1)
  1893.         and 7 ;right shift
  1894.         jr z,sweep1noshift
  1895.         ld b,a
  1896. sweep1shift0
  1897.         srl e
  1898.         djnz sweep1shift0
  1899. sweep1noshift
  1900.         endif
  1901.  
  1902.         ld hl,SND_SQUARE1_REG+3
  1903.         ld a,(hl)
  1904.         dec hl
  1905.         ld l,(hl)
  1906.         and 7
  1907.         ld h,a
  1908.        
  1909.         if SWEEP
  1910.         ld a,(SND_SQUARE1_REG+1)
  1911.         or a
  1912.         jp p,sweep1disabled
  1913. ;add/sub sweep:
  1914.          scf ;for sq1 only!
  1915.         sbc hl,de
  1916.         and 8
  1917.         jr nz,$+5 ;decrease wavelength
  1918.          inc hl ;for sq1 only!
  1919.          add hl,de
  1920.          add hl,de ;increase wavelength
  1921. sweep1disabled
  1922.         endif
  1923.  
  1924.         ld a,1
  1925.         ld b,0xff
  1926.         out (c),a
  1927.         ld b,0xbf
  1928.         out (c),h
  1929.         dec a
  1930.         ld b,0xff
  1931.         out (c),a
  1932.         ld b,0xbf
  1933.         out (c),l
  1934.  
  1935.         if SWEEP
  1936. sweep2=$+1
  1937.         ld de,0 ;сколько бит в этом счётчике??? будем считать, что 8
  1938.         ld a,(SND_SQUARE2_REG+1)
  1939.         rra
  1940.         rra
  1941.         rra
  1942.         rra
  1943.         and 7 ;sweep rate
  1944.         inc a
  1945.         ld b,a
  1946. sweep2counter=$+1
  1947.         ld a,0
  1948.         sub 2 ;2 "sound frames"
  1949.         jr nc,$+3
  1950.         add a,b ;sweep rate
  1951.         ld (sweep2counter),a
  1952.         jr nc,sweep2noinc
  1953.         inc e
  1954.         ld (sweep2),de
  1955. sweep2noinc
  1956.         ld a,(SND_SQUARE2_REG+1)
  1957.         and 7 ;right shift
  1958.         jr z,sweep2noshift
  1959.         ld b,a
  1960. sweep2shift0
  1961.         srl e
  1962.         djnz sweep2shift0
  1963. sweep2noshift
  1964.         endif
  1965.        
  1966.         ld hl,SND_SQUARE2_REG+3
  1967.         ld a,(hl)
  1968.         dec hl
  1969.         ld l,(hl)
  1970.         and 7
  1971.         ld h,a
  1972.        
  1973.         if SWEEP
  1974.         ld a,(SND_SQUARE2_REG+1)
  1975.         or a
  1976.         jp p,sweep2disabled
  1977. ;add/sub sweep:
  1978.         sbc hl,de
  1979.         ld a,(SND_SQUARE2_REG+1)
  1980.         and 8
  1981.         jr nz,$+4 ;decrease wavelength
  1982.          add hl,de
  1983.          add hl,de ;increase wavelength
  1984. sweep2disabled
  1985.         endif
  1986.  
  1987.         ld a,5
  1988.         ld b,0xff
  1989.         out (c),a
  1990.         ld b,0xbf
  1991.         out (c),h
  1992.         dec a
  1993.         ld b,0xff
  1994.         out (c),a
  1995.         ld b,0xbf
  1996.         out (c),l
  1997.  
  1998.         ld d,0x0f ;all channels enabled
  1999.        
  2000.         ld a,11
  2001.         ld b,0xff
  2002.         out (c),a
  2003.         ld hl,SND_TRIANGLE_REG+3
  2004.         ld a,(hl)
  2005.         and 7
  2006.         dec hl
  2007.         ld e,(hl)
  2008.          sla e
  2009.          adc a,a
  2010.          jr z,$+2+2+2 ;иначе немного фальшивят верхние ноты в басу
  2011.           srl a
  2012.           rr e
  2013.          srl a
  2014.          rr e
  2015.          ld hl,curtimer
  2016.          bit 0,(hl)
  2017.          jr z,$+3
  2018.          inc e ;уседняем фальшь по 2 прерываниям
  2019.          srl a
  2020.          rr e
  2021.          jr nz,$+4
  2022.          res 1,d ;disable triangle if freq=0
  2023.         ld b,0xbf
  2024.         out (c),e
  2025.         ;ld e,12;3
  2026.         ;ld b,0xff
  2027.         ;out (c),e
  2028.         ;ld b,0xbf
  2029.         ;out (c),a
  2030.  
  2031.         ld a,6
  2032.         ld b,0xff
  2033.         out (c),a
  2034.         ld a,(SND_NOISE_REG+2)
  2035.         add a,a
  2036.         ld b,0xbf
  2037.         out (c),a
  2038.  
  2039. ;counters
  2040.         ld a,(SND_TRIANGLE_REG)
  2041.         or a
  2042.         jp m,trianglecount
  2043. ;linear counter load, stop length counter
  2044.         ;and 0x7f
  2045.         ld (trianglelinearcounter),a
  2046.         ;jp trianglehalt
  2047. trianglecount
  2048. trianglelinearcounter=$+1
  2049.         ld a,0
  2050.         sub 4
  2051.         jr nc,$+3
  2052.          xor a
  2053.         ld (trianglelinearcounter),a ;ld (SND_TRIANGLE_REG),a
  2054.         jr nz,$+4
  2055.         res 1,d ;triangle disabled because of linear counter=0
  2056.         ld a,(SND_COUNTER+8) ;(SND_TRIANGLE_REG+3) ;counter register, load it = f(SND_TRIANGLE_REG+3) at write there
  2057.         sub 1;2
  2058.         jr nc,$+3
  2059.         xor a
  2060.         ld (SND_COUNTER+8),a ;(SND_TRIANGLE_REG+3),a
  2061.         jr nz,$+4
  2062.         res 1,d ;triangle disabled because of counter=0
  2063. trianglehalt
  2064.  
  2065.         ld a,(SND_SQUARE2_REG)
  2066.         bit 5,a
  2067.         jp nz,square2halt ;counter disable
  2068.         ld a,(SND_COUNTER+4) ;(SND_SQUARE2_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+3) at write there
  2069.         sub 1;2
  2070.         jr nc,$+3
  2071.         xor a
  2072.         ld (SND_COUNTER+4),a ;(SND_SQUARE2_REG+3),a
  2073.         jr nz,$+4
  2074.         res 2,d ;disabled because of counter=0
  2075. square2halt
  2076.  
  2077.         ld a,(SND_SQUARE1_REG)
  2078.         bit 5,a
  2079.         jp nz,square1halt ;counter disable
  2080.         ld a,(SND_COUNTER+0) ;(SND_SQUARE1_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+1) at write there
  2081.         sub 1;2
  2082.         jr nc,$+3
  2083.         xor a
  2084.         ld (SND_COUNTER+0),a ;(SND_SQUARE1_REG+3),a
  2085.         jr nz,$+4
  2086.         res 0,d ;disabled because of counter=0
  2087. square1halt
  2088.  
  2089.         ld a,(SND_NOISE_REG)
  2090.         bit 5,a
  2091.         jp nz,noisehalt ;counter disable
  2092.         ld a,(SND_COUNTER+12) ;(SND_SQUARE1_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+1) at write there
  2093.         sub 16;1;2
  2094.         jr nc,$+3
  2095.         xor a
  2096.         ld (SND_COUNTER+12),a ;(SND_SQUARE1_REG+3),a
  2097.         jr nz,$+4
  2098.         res 3,d ;disabled because of counter=0
  2099. noisehalt
  2100.  
  2101. ;channel enable
  2102.         ld a,7
  2103.         ld b,0xff
  2104.         out (c),a
  2105.         ld hl,SND_MASTERCTRL_REG ;%???DNT21
  2106.         ld a,(hl)
  2107.        if 1==1
  2108.         add a,0x2 ;%00? -> %01? (bit 2 reset), %11? -> %00? (bit 2 reset)
  2109.         and 0x4 ;was %00? or %11? - no swap
  2110.         ld a,(hl)
  2111.         jr z,noswap21 ;bit 2 reset - no swap
  2112.         xor 0x6 ;swap %01? <-> %10?
  2113. noswap21
  2114.        else
  2115.         rra ;%??????T?
  2116.         xor (hl)
  2117.         and 0x02
  2118.         xor (hl) ;%???DNTT1
  2119.         and 0xfb ;%???DN0T1
  2120.         bit 1,(hl)
  2121.         jr z,$+4
  2122.         or 0x04  ;%???DN2T1
  2123.        endif
  2124.        ;or 8 ;noise
  2125.         and d
  2126.         ld d,a
  2127.         cpl
  2128.         ;and 7
  2129.          and 5 ;enable B (тихая огибающая) ;or 2 ;disable triangle(B) here
  2130.         or 0x38 ;disable noise
  2131.          bit 3,d
  2132.          jr z,$+2+2+2
  2133.          set 1,a ;disable tone in B
  2134.          res 4,a ;enable noise in B
  2135.         ld b,0xbf
  2136.         out (c),a
  2137.  
  2138. ;Only a write out to $4003/$4007/$400F will reset the current envelope decay counter to a known state (to $F, the maximum volume level) for the appropriate channel's envelope decay hardware.
  2139. ;Otherwise, the envelope decay counter is always counting down (by 1) at the frequency currently contained in the volume / envelope decay rate bits (even when envelope decays are disabled (setting bit 4)), except when the envelope decay counter contains a value of 0, and envelope decay looping (bit 5) is disabled (0).
  2140. ;vol
  2141.         ld e,8
  2142.         ld b,0xff
  2143.         out (c),e
  2144.         ld a,(SND_SQUARE1_REG) ;bit4=constant volume, or else envelope
  2145.         bit 4,a
  2146.         jr nz,vol1const
  2147.         ld a,(SND_DECAYVOL+0)
  2148. vol1const
  2149.         and 15
  2150.         ld hl,tvolume
  2151.         add a,l
  2152.         ld l,a
  2153.         adc a,h
  2154.         sub l
  2155.         ld h,a
  2156.         ld l,(hl)
  2157.         ld b,0xbf
  2158.         out (c),l
  2159.        
  2160.         ld hl,SND_SQUARE1_REG
  2161.         ld a,(hl)
  2162.         and 15 ;decay rate
  2163.         inc a
  2164.         ld b,a
  2165. vol1decaycounter=$+1
  2166.         ld a,0
  2167.         sub 4 ;4 "sound frames"
  2168.         jr nc,$+3
  2169.         add a,b ;decay rate
  2170.         ld (vol1decaycounter),a
  2171.         jr nc,vol1nodecay
  2172.          ld a,(SND_DECAYVOL+0)
  2173.          dec a
  2174.         jp p,vol1noenddecay
  2175.          and 0xf
  2176.         bit 5,(hl)
  2177.         jr nz,vol1noenddecay ;decay looping enabled
  2178.          xor a
  2179. vol1noenddecay
  2180.          ld (SND_DECAYVOL+0),a
  2181. vol1nodecay
  2182.  
  2183.         ld e,10
  2184.         ld b,0xff
  2185.         out (c),e
  2186.         ld a,(SND_SQUARE2_REG) ;bit4=constant volume, or else envelope
  2187.         bit 4,a
  2188.         jr nz,vol2const
  2189.         ld a,(SND_DECAYVOL+4)
  2190. vol2const
  2191.         and 15
  2192.         ld hl,tvolume
  2193.         add a,l
  2194.         ld l,a
  2195.         adc a,h
  2196.         sub l
  2197.         ld h,a
  2198.         ld l,(hl)
  2199.         ld b,0xbf
  2200.         out (c),l
  2201.        
  2202.         ld hl,SND_SQUARE2_REG
  2203.         ld a,(hl)
  2204.         and 15 ;decay rate
  2205.         inc a
  2206.         ld b,a
  2207. vol2decaycounter=$+1
  2208.         ld a,0
  2209.         sub 4 ;4 "sound frames"
  2210.         jr nc,$+3
  2211.         add a,b ;decay rate
  2212.         ld (vol2decaycounter),a
  2213.         jr nc,vol2nodecay
  2214.          ld a,(SND_DECAYVOL+4)
  2215.          dec a
  2216.         jp p,vol2noenddecay
  2217.          and 0xf
  2218.         bit 5,(hl)
  2219.         jr nz,vol2noenddecay ;decay looping enabled
  2220.          xor a
  2221. vol2noenddecay
  2222.          ld (SND_DECAYVOL+4),a
  2223. vol2nodecay
  2224.  
  2225.         ld e,9
  2226.         ld b,0xff
  2227.         out (c),e
  2228.         ld a,(SND_NOISE_REG) ;bit4=constant volume, or else envelope
  2229.         bit 4,a
  2230.         jr nz,noiseconst
  2231.         ld a,(SND_DECAYVOL+12)
  2232. noiseconst
  2233.         and 15
  2234.         ld hl,tvolume
  2235.         add a,l
  2236.         ld l,a
  2237.         adc a,h
  2238.         sub l
  2239.         ld h,a
  2240.         ld a,(hl)
  2241.         ;ld b,0xbf
  2242.         ;out (c),l
  2243.  
  2244.         ;ld e,9
  2245.         ;ld b,0xff
  2246.         ;out (c),e
  2247.          bit 3,d ;noise
  2248.          jr nz,notrianglevolumeout
  2249.         xor a
  2250.          bit 1,d ;triangle
  2251.          jr z,$+4
  2252.         ld a,16
  2253. notrianglevolumeout
  2254.         ld b,0xbf
  2255.         out (c),a
  2256.          ;and 15
  2257.          ;jr nz,$
  2258.        
  2259.         ld hl,SND_NOISE_REG
  2260.         ld a,(hl)
  2261.         and 15 ;decay rate
  2262.         inc a
  2263.         ld b,a
  2264. noisedecaycounter=$+1
  2265.         ld a,0
  2266.         sub 4 ;4 "sound frames"
  2267.         jr nc,$+3
  2268.         add a,b ;decay rate
  2269.         ld (noisedecaycounter),a
  2270.         jr nc,noisenodecay
  2271.          ld a,(SND_DECAYVOL+12)
  2272.          dec a
  2273.         jp p,noisenoenddecay
  2274.          and 0xf
  2275.         bit 5,(hl)
  2276.         jr nz,noisenoenddecay ;decay looping enabled
  2277.          xor a
  2278. noisenoenddecay
  2279.          ld (SND_DECAYVOL+12),a
  2280. noisenodecay
  2281.        
  2282.         endif
  2283.  
  2284.         if RESTOREPG16K
  2285. ;curpg4000=$+1
  2286. ;        ld a,0
  2287.         pop af
  2288.         SETPG16K
  2289.         endif
  2290.  
  2291.         pop de
  2292.         pop bc
  2293.         pop af
  2294.        
  2295. on_int_hl=$+1
  2296.         ld hl,0
  2297.         if MULTITASKING==0
  2298. on_int_sp2=$+1
  2299.         ld sp,0
  2300.         ei
  2301. on_int_jp=$+1
  2302.         jp 0
  2303.        
  2304.         else
  2305.  
  2306.         ld sp,tempintstack
  2307.         push de
  2308.         ex de,hl
  2309. ;(intjp)=адрес выхода
  2310. ;de="hl", в стеке "de"
  2311.         jp 0x0038+5
  2312.  
  2313. ;        dw 0
  2314. ;tempintstack=$ ;нельзя тут (ниже 0x3b00)
  2315.  
  2316. ;вход в стандартный обработчик:
  2317.         ;ex de,hl ;de="hl", hl="de"
  2318.         ;ex (sp),hl ;hl=адрес выхода, de="hl", в стеке "de"
  2319.         ;ld (intjp),hl ;TODO писать не прямо в intjp, а в промежуточную локацию (иначе хвост обработчика нельзя с ei - он сам не может сменить режим обработки прерывания после jp)
  2320. ;(intjp)=адрес выхода
  2321. ;de="hl", в стеке "de"
  2322.         ;ld l,a
  2323. ;user_fdvalue6=$+1
  2324.         ;ld a,fd_system
  2325.         ;out (0xfd),a ;10 b
  2326.  
  2327. on_int_q
  2328. ;на выходе из стандартного обработчика в стеке "de"
  2329. ;восстановим как надо
  2330. on_int_sp2=$+1
  2331.         ld sp,0
  2332. on_int_jp=$+1
  2333.         jp 0
  2334.  
  2335.         endif
  2336.  
  2337. SND_COUNTER
  2338. SND_DECAYVOL=$+1
  2339.         ds 4+4+4+2 ;sq1,sq2,tri,noise (2 bytes used from 4)
  2340.        
  2341. tvolume
  2342.         db 0,9,10,11, 12,12,13,13, 13,14,14,14, 15,15,15,15
  2343.        
  2344. ;что-то не так с этой таблицей
  2345. tcounterload
  2346.         db 0x7f,0x05
  2347.         db 0x01,0x0a
  2348.         db 0x02,0x14
  2349.         db 0x03,0x28
  2350.         db 0x04,0x50
  2351.         db 0x05,0x1e
  2352.         db 0x06,0x07
  2353.         db 0x07,0x0d
  2354.        
  2355.         db 0x08,0x06
  2356.         db 0x09,0x0c
  2357.         db 0x0a,0x18
  2358.         db 0x0b,0x30
  2359.         db 0x0c,0x60
  2360.         db 0x0d,0x24
  2361.         db 0x0e,0x08
  2362.         db 0x0f,0x10
  2363.        
  2364. gettimer
  2365. ;out: hl=timer
  2366. ;суммируем оба таймера - вдруг было системное прерывание
  2367.         if OSCALLS
  2368.         OS_GETTIMER ;hlde=timer
  2369.         endif
  2370. curtimer=$+1
  2371.         ld hl,0
  2372.         if OSCALLS
  2373.         add hl,de
  2374.         endif
  2375.         ret
  2376.  
  2377.         ;include "smbsound.asm"
  2378.         ;include "smbmusic.asm"
  2379.        
  2380. reservepage
  2381. ;new page, set page in textpages, npages++, set page in #c000
  2382. ;nz=error
  2383.         OS_NEWPAGE
  2384.         or a
  2385.         ret nz
  2386. npages=$+1
  2387.         ld hl,filepages
  2388.         ld (hl),e
  2389.         inc l
  2390.         ld (npages),hl
  2391.         ld a,e
  2392.         SETPG32KHIGH
  2393.         xor a
  2394.         ret ;z
  2395.        
  2396.  
  2397. DEMOLONGLINE=1
  2398.  
  2399. demooff
  2400. ;выключение демы, играем и пишем с клавиатуры
  2401.          ld a,55; ;scf ;201 ;ret
  2402.          ld (readdemo),a
  2403.          ;ld a,0x77
  2404.          ;ld (getbyte_opcode),a
  2405.          xor a
  2406.          ld (InjurePlayer_PiranhaPlant),a
  2407.          ;jp democontinue ;иначе будет вечная пауза
  2408. democontinue
  2409. ;продолжение после брякпоинта
  2410.         xor a
  2411.         ld (readdemo_stopflag),a
  2412.         ret
  2413.  
  2414.         macro NEXTBYTEFAST
  2415.         inc l
  2416.         call z,getbyte_inch_pp
  2417.         endm
  2418.         macro NEXTBYTEEND
  2419.         ld (getbyte_addr),hl
  2420.         endm
  2421.        
  2422. writedemo
  2423. ;сейчас указатель на разделителе после кнопок джойстика
  2424. ;a=keys
  2425. ;DEMOLONGLINE=1!!!
  2426.         push af
  2427.         call getbyte_setpg
  2428.         NEXTBYTEFAST
  2429.         ld (hl),'+'
  2430.        
  2431.         ld b,8
  2432. writedemo0
  2433.         NEXTBYTEFAST
  2434.         ld (hl),'.'
  2435.         djnz writedemo0
  2436.        
  2437.         NEXTBYTEFAST
  2438.         ld (hl),'|'
  2439.         NEXTBYTEFAST
  2440.         ld (hl),0x0d
  2441.         NEXTBYTEFAST
  2442.         ld (hl),0x0a
  2443.         NEXTBYTEFAST
  2444.         ld (hl),'|'
  2445.         NEXTBYTEFAST
  2446.         ld (hl),'.'
  2447.         NEXTBYTEFAST
  2448.         ld (hl),'.'
  2449.         NEXTBYTEFAST
  2450.         ld (hl),'|'
  2451.        
  2452.         pop af
  2453.         push af
  2454.         ld c,a
  2455.  
  2456.         if DEMOLONGLINE
  2457.         xor a
  2458.         ld b,c
  2459.         rr c
  2460.         rla
  2461.         rr c
  2462.         rla
  2463.         rr c
  2464.         rla
  2465.         rr c
  2466.         rla ;%0000UDLR
  2467.         xor b
  2468.         and 0x0f
  2469.         xor b
  2470.         ld c,a
  2471.         endif
  2472.  
  2473.         ld b,8
  2474. writedemo1
  2475.         NEXTBYTEFAST
  2476.         rrc c
  2477.         ld (hl),'.'
  2478.         jr nc,$+4
  2479.         ld (hl),'Z'
  2480.         djnz writedemo1
  2481.        
  2482.         NEXTBYTEEND
  2483.  
  2484.         call setpgs_code
  2485.         pop af
  2486.         ret
  2487.  
  2488. readdemo
  2489.         display "readdemo=",$
  2490.         or a ;/scf
  2491.         jr c,writedemo
  2492. readdemo_stopflag=$
  2493.         nop ;/ret
  2494.  
  2495.         ;jr $
  2496.         call getbyte_setpg
  2497.        
  2498.         if 1==0 ;однобайтный формат дем
  2499.         ld a,(hl)
  2500. ;a=buttons = %R?D?t?BA
  2501.         ld b,8
  2502.         rra
  2503.         rl c
  2504.         djnz $-3
  2505.         NEXTBYTEEND
  2506.         ld a,c
  2507.        
  2508. ;a=buttons
  2509. ;bit - button (ZX key)
  2510. ;7 - A (A)
  2511. ;6 - B (S)
  2512. ;5 - Select (Space)
  2513. ;4 - Start (Enter)
  2514. ;3 - Up (7)
  2515. ;2 - Down (6)
  2516. ;1 - Left (5)
  2517. ;0 - Right (8)
  2518.         else
  2519.        
  2520. ;"|0|RLDUTsBA|||",0x0a = 15 bytes, реально начинаем на 4 байта раньше
  2521. ;"|.r|UDLRSsBA|........|",0x0d,0x0a = 24 bytes, реально начинаем на 12 байт раньше
  2522. ;лучше перейти на короткий формат, а то 6000t после оптимизации (один байт = 194t)
  2523.         if DEMOLONGLINE
  2524.         ld d,12+4
  2525.         else
  2526.         ld d,3+4
  2527.         endif
  2528.        
  2529. readdemo0
  2530.         NEXTBYTEFAST
  2531.         ld a,(hl)
  2532.         add a,256-'A'
  2533.         rr e
  2534.         dec d
  2535.         jp nz,readdemo0
  2536.  
  2537.         ld d,0x80
  2538. readdemo1
  2539.         NEXTBYTEFAST
  2540.         ld a,(hl)
  2541.         add a,256-'A'
  2542.         rr d
  2543.         jp nc,readdemo1
  2544.        
  2545.         NEXTBYTEEND
  2546.        
  2547.         if DEMOLONGLINE
  2548.          ;ld a,e
  2549.          ;and 0x40 ;reset
  2550.          ;cp 0
  2551.          ;ld ($-1),a
  2552.         bit 6,e
  2553.          jp z,readdemo_noreset
  2554.         ;or a
  2555.         ;jr nz,readdemo_noreset
  2556.         ;pop af
  2557.         ;jp Start
  2558.         if FASTDEMOBEFOREBREAKPOINT
  2559.         push de
  2560.         xor a
  2561.         ld (skipPPU),a
  2562.         call EmulatePPU
  2563.         call EmulatePPU
  2564.         pop de
  2565.         endif
  2566.         ld a,201
  2567.         ld (readdemo_stopflag),a
  2568. readdemo_noreset
  2569.  
  2570.         xor a
  2571.         ld b,d
  2572.         rr d
  2573.         rla
  2574.         rr d
  2575.         rla
  2576.         rr d
  2577.         rla
  2578.         rr d
  2579.         rla ;%0000UDLR
  2580.         xor b
  2581.         and 0x0f
  2582.         xor b
  2583.        
  2584.         else
  2585.        
  2586.         ld a,d
  2587.        
  2588.         endif
  2589.        
  2590.         endif
  2591. ;a=buttons
  2592. ;bit - button (ZX key)
  2593. ;7 - A (A)
  2594. ;6 - B (S)
  2595. ;5 - Select (Space)
  2596. ;4 - Start (Enter)
  2597. ;3 - Up (7)
  2598. ;2 - Down (6)
  2599. ;1 - Left (5)
  2600. ;0 - Right (8)
  2601.         push af
  2602.         call setpgs_code
  2603.         pop af
  2604.         ret
  2605.        
  2606. getbyte_setpg
  2607. ;портит hl,bc
  2608. ;не портит de
  2609. ;out: a=pg, hl=addr in pg
  2610. getbyte_addr=$+1 ;реально читать начнём со следующего адреса
  2611.         ;ld hl,0xffe0+5 ;148974
  2612. ;правдоподобно только 5..6, что-то не так с отскоком от врага?
  2613.         ;ld hl,0xffe0+14 ;53672
  2614.         ;ld hl,0xc260+4 ;53672
  2615. ;было (когда старт нажимался слишком поздно - уже во встроенной деме)
  2616. ;12..13 проход через трубу медленно, сдох на монстре
  2617. ;14 (+4) проход через трубу с задержкой справа, потом застрял на лестнице
  2618. ;15 не допрыгнул до трубы с бонусом
  2619. ;16-20 ещё хуже
  2620.         ;ld hl,0xd2c8-12-1+(15*24) ;1904330 (pg1)
  2621. ;11..13 сбил кирпич, пропрыгал две трубы
  2622. ;14 прошёл 1-1, сдох на черепахе в 1-2
  2623. ;15 прошёл 1-1, сдох на грибе после черепахи в 1-2
  2624. ;16 нырнул в трубу, но не собрал монетки, а застрял
  2625. ;17..20 не стартует
  2626.         ;ld hl,0xc111-4-1+(16*15) ;351918
  2627. ;11..14 - застреваем после убийства второго монстра
  2628. ;15 - перепрыгиваем его, застреваем дальше
  2629. ;16 - пролезаем через трубу, застреваем на лестнице
  2630. ;17..20- умираем на втором монстре
  2631.         ;ld hl,0xc0f4-4-1+(7*15) ;307549
  2632. ;7..8 - довольно быстро бежим, но попадаем на первого монстра
  2633. ;9 прыжок явно мимо
  2634. ;12 медленно
  2635. ;16..20 не стартует
  2636.         ld hl,0xc090-12-1 +(4*24) ;1775978 (cropped)
  2637. ;0,1 - проходим world 1-1 (при jr RImpd застреваем возле замка)
  2638. ;2,3 - застреваем на конечной лестнице 1-1 (при jr RImpd застреваем в трубе)
  2639. ;4 - доходим дальше в 1-2 (при jr RImpd застреваем возле замка)
  2640. ;5,6,7,8,9,10,11,12,13,14,15,16,17,18 - не проходим 1-1 (18 при jr RImpd застреваем возле замка)
  2641. ;19,20 - застреваем на конечной лестнице 1-1 (при jr RImpd застреваем возле замка)
  2642. ;21,22 - проходим world 1-1
  2643. ;23,24 - застреваем на конечной лестнице 1-1
  2644. ;25 - доходим дальше в 1-2
  2645. getbyte_pg=$+1
  2646.         ld a,(filepages)
  2647.         SETPG32KHIGH
  2648.         ret
  2649.        
  2650. getbyte_inch_pp
  2651. ;не портит bc, переустанавливает hl в начале новой страницы (тогда же щёлкает страницу)
  2652. ;l=0
  2653.         inc h
  2654.         ret nz
  2655.          ld hl,getbyte_pg
  2656.          inc (hl)
  2657.         push bc
  2658. getbyte_inch_memoryretry_m
  2659.         ld c,(hl)
  2660.         ld b,filepages/256
  2661. getbyte_inch_memoryretry
  2662.         ld a,(bc)
  2663.         or a
  2664.         jr z,getbyte_inch_newpg
  2665.         SETPG32KHIGH
  2666.         pop bc
  2667.          ld hl,0xc000
  2668.         ret
  2669. getbyte_inch_newpg
  2670.          push bc
  2671.          push de
  2672.           halt ;чтобы не сработало системное прерывание
  2673.          call reservepage ;nz=error ;портит все регистры (но нам hl не важен)
  2674.           ld a,(imer_curscreen_value)
  2675.           ld bc,0x7ffd
  2676.           out (c),a
  2677.          pop de
  2678.          pop bc
  2679.          jr z,getbyte_inch_memoryretry
  2680.          ld hl,getbyte_pg
  2681.          dec (hl)
  2682.         jr getbyte_inch_memoryretry_m ;no more memory
  2683.        
  2684.  
  2685. savedemo
  2686.         ld de,filename2
  2687.         OS_CREATEHANDLE
  2688. ;b=new file handle
  2689.         push af
  2690.         ld a,b
  2691.         ld (filehandle),a
  2692.         pop af
  2693.         ;or a
  2694.         ;ret nz
  2695.        
  2696.         ld hl,0
  2697.         ld de,0
  2698.         ld a,0
  2699. nvview_save0
  2700.         ;push de
  2701.         ;push hl
  2702.         ;call reservepage
  2703.         ;pop hl
  2704.         ;pop de
  2705.         ;ret nz ;no memory
  2706.         push af
  2707.         ld c,a
  2708.         ld b,filepages/256
  2709.         ld a,(bc)
  2710.         SETPG32KHIGH
  2711.        
  2712.         push de
  2713.         push hl
  2714.         ld de,0xc000
  2715.         ld hl,0x4000
  2716. ;DE = Buffer address, HL = Number of bytes to read
  2717.         push hl
  2718.         ld a,(filehandle)
  2719.         ld b,a
  2720.         OS_WRITEHANDLE
  2721. ;hl=actual size
  2722. ;hl=loaded bytes
  2723.         ld b,h
  2724.         ld c,l
  2725.         pop hl ;Number of bytes to read
  2726.         or a
  2727.         sbc hl,bc ;z=loaded as requested
  2728. ;bc=loaded bytes
  2729.         pop hl
  2730.         pop de
  2731.         pop af
  2732. ;hlde=size
  2733. ;z=loaded as requested
  2734.         ;ex de,hl
  2735.         ;add hl,bc
  2736.         ;ex de,hl
  2737.         ;jr nc,$+3
  2738.         ;inc hl
  2739.         ;jr z,nvview_save0
  2740.         inc a
  2741.         ld ix,npages
  2742.         cp (ix)
  2743.         jr nz,nvview_save0
  2744. ;hlde=true file size (for TRDOSFS)
  2745.         ;ld (fcb+FCB_FSIZE),de
  2746.         ;ld (fcb+FCB_FSIZE+2),hl
  2747.  
  2748.         call closestream_file
  2749.         jp setpgs_code
  2750.  
  2751. gfxfilename
  2752.         db "smb.nes",0
  2753. filename
  2754.         db "antipac.fm2",0
  2755. filename2
  2756.         db "demo.fm2",0
  2757.         include "../../_sdk/file.asm"
  2758. tnofile
  2759.         db "smb.nes not found",0x0d,0x0a,0
  2760.  
  2761. ;oldtimer
  2762. ;       ds 2
  2763.  
  2764.         ;display "free before 0x2000=",0x2000-$
  2765.         ds 0x2000-$
  2766. ;tile gfx: 2 256-tile maps
  2767. ;16bytes/tile: 8bytes low bit, 8bytes high bit
  2768. tilegfx
  2769.         ds 0x2000 ;incbin "smbtiles"
  2770.        
  2771.         include "SMBDIS.ASM"
  2772.  
  2773. end
  2774.  
  2775.         ;display "End=",end
  2776.         ;display "Free after end=",/d,0xc000-end
  2777.         ;display "Size ",/d,end-begin," bytes"
  2778.        
  2779.         savebin "smb.com",begin,end-begin
  2780.        
  2781.         ;LABELSLIST "user.l"
  2782.