?login_element?

Subversion Repositories NedoOS

Rev

Rev 660 | 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=0;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 ;dehl=timer
  259.         ;ld (oldtimer),hl
  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.         ei
  1009.         ret
  1010. oldimer
  1011.         jp on_int ;заменится на код из 0x0038
  1012.         jp 0x0038+3
  1013.  
  1014. setpgs_code
  1015. codepage4000=$+1
  1016.         ld a,0
  1017.          if RESTOREPG16K
  1018.          ;ld (curpg4000),a
  1019.          endif
  1020.         SETPG16K
  1021. codepage8000=$+1
  1022.         ld a,0
  1023.         SETPG32KLOW
  1024. codepagec000=$+1
  1025.         ld a,0
  1026.         SETPG32KHIGH
  1027.         ret
  1028.        
  1029. setpgs_scr
  1030. tilepage=$+1
  1031.         ld a,0
  1032.          if RESTOREPG16K
  1033.          ;ld (curpg4000),a
  1034.          endif
  1035.         SETPG16K
  1036. ;setpgs_scr_low=$+1
  1037. ;        ld a,0;pgscr0_0 ;scr0_0
  1038.         call getuser_scr_low
  1039.         SETPG32KLOW
  1040. ;setpgs_scr_high=$+1
  1041. ;        ld a,0;pgscr0_1 ;scr0_1
  1042.         call getuser_scr_high
  1043.         SETPG32KHIGH
  1044.         ret
  1045.  
  1046. getuser_scr_low
  1047. getuser_scr_low_patch=$+1
  1048. getuser_scr_low_patchN=0xff&(user_scr0_low^user_scr1_low)
  1049.         ld a,(user_scr0_low) ;ok
  1050.         ret
  1051.  
  1052. getuser_scr_high
  1053. getuser_scr_high_patch=$+1
  1054. getuser_scr_high_patchN=0xff&(user_scr0_high^user_scr1_high)
  1055.         ld a,(user_scr0_high) ;ok
  1056.         ret
  1057.  
  1058.  
  1059.         align 256
  1060. tytoscr
  1061.         dup 200
  1062.         db (($&0xff)*40)&0xff
  1063.         edup
  1064.         align 256
  1065.         dup 200
  1066.         db (($&0xff)*40)/256 + 0x80
  1067.         edup
  1068.  
  1069.         macro NEXTCOLUMN
  1070.         bit 6,h
  1071.         set 6,h
  1072.         jr z,$+2+4+2+2+1
  1073.         ld a,h
  1074.         xor 0x60
  1075.         ld h,a
  1076.         and 0x20
  1077.         jr nz,$+3
  1078.         inc hl
  1079.         endm
  1080.  
  1081.         macro COUNTSCRADDR
  1082.         add a,(hl)
  1083.         inc h
  1084.          ld c,a
  1085.         ;ld h,(hl)
  1086.          adc a,(hl)
  1087.          sub c
  1088.        ld l,c;a
  1089.        ;ld a,b
  1090.        ;adc a,h
  1091.         ;inc h
  1092.         ;ld l,c ;x
  1093.         ;add a,(hl) ;8+7=15t, а если rra:srl a=12t, плюс выигрываем 2 команды bit
  1094.          ;inc h
  1095.          ;ld a,(hl)
  1096.          ;ld (prcharxy_jr),a ;4+7+13+12(jr) = 35t, а если bit:jr z:bit:jr z, то в среднем 16+7+12=35t тоже
  1097.         endm
  1098.  
  1099.         macro NEXTCOLUMNS0
  1100.         ld h,a ;.00
  1101.         push hl
  1102.         set 6,h ;.10
  1103.         push hl
  1104.         xor 0x20
  1105.         ld h,a ;.01
  1106.         push hl
  1107.         set 6,h ;.11
  1108.         endm
  1109.         macro NEXTCOLUMNS1
  1110.         ld c,a
  1111.         xor 0x40
  1112.         ld h,a ;.10
  1113.         push hl
  1114.         xor 0x60
  1115.         ld h,a ;.01
  1116.         push hl
  1117.         set 6,h ;.11
  1118.         push hl
  1119.         ld h,c ;.00
  1120.         inc hl
  1121.         endm
  1122.         macro NEXTCOLUMNS2
  1123.         ld h,a
  1124.         set 5,h ;.01
  1125.         push hl
  1126.         set 6,h ;.11
  1127.         push hl
  1128.         ld h,a ;.00
  1129.         inc hl
  1130.         push hl
  1131.         set 6,h ;.10
  1132.         endm
  1133.         macro NEXTCOLUMNS3
  1134.         ld c,a
  1135.         xor 0x60
  1136.         ld h,a ;.11
  1137.         push hl
  1138.         ld h,c ;.00
  1139.         inc hl
  1140.         push hl
  1141.         set 6,h ;.10
  1142.         push hl
  1143.          ld a,h ;нельзя старое, т.к. было inc hl
  1144.          xor 0x60
  1145.          ld h,a ;.01
  1146.         endm
  1147.  
  1148. prcharxy
  1149. ;de=gfx
  1150. ;la=yx
  1151. ;CY=0
  1152.         ld h,tytoscr/256
  1153.        rra
  1154.        jr c,prcharxy_nextcolumns13
  1155.        rra;srl a
  1156.        jr c,prcharxy_nextcolumns2
  1157. prcharxy_nextcolumns0
  1158.         COUNTSCRADDR
  1159.         NEXTCOLUMNS0
  1160.         jp prcharxy_scrok
  1161. prcharxy_nextcolumns2
  1162.         COUNTSCRADDR
  1163.         NEXTCOLUMNS2
  1164.         jp prcharxy_scrok
  1165. prcharxy_nextcolumns13
  1166.        srl a
  1167.        jr c,prcharxy_nextcolumns3
  1168. prcharxy_nextcolumns1
  1169.         COUNTSCRADDR
  1170.         NEXTCOLUMNS1
  1171.         jp prcharxy_scrok
  1172. prcharxy_nextcolumns3
  1173.         COUNTSCRADDR
  1174.         NEXTCOLUMNS3
  1175. prcharxy_scrok
  1176.  
  1177.         macro SHOWBYTEBEHIND
  1178.          inc d;e
  1179.         cp (hl) ;scr
  1180.         jr nz,$+5
  1181.         ld a,(de)
  1182.         ld (hl),a ;scr
  1183.         xor a
  1184.          inc d;e
  1185.         endm
  1186.         macro SHOWBYTEBEHIND_LAST
  1187.         cp (hl) ;scr
  1188.         ret nz
  1189.          inc d;e
  1190.         ld a,(de)
  1191.         ld (hl),a ;scr
  1192.         ret
  1193.         endm
  1194.        
  1195.         macro SHOWBYTE ;TODO pop de
  1196.         ex de,hl
  1197.         ld a,(de) ;scr
  1198.         and (hl) ;font
  1199.          inc h;l
  1200.         or (hl)
  1201.          inc h;l
  1202.         ld (de),a ;scr
  1203.         ex de,hl
  1204.         endm
  1205.         macro SHOWBYTE_LAST ;TODO pop de
  1206.         ex de,hl
  1207.         ld a,(de) ;scr
  1208.         and (hl) ;font
  1209.          inc h;l
  1210.         or (hl)
  1211.         ld (de),a ;scr
  1212.         ret
  1213.         endm
  1214.        
  1215.         ;ld a,(de) ;font
  1216.         ;ld (hl),a ;scr
  1217.         ; inc d;e
  1218.         ;add hl,bc
  1219.        
  1220.        
  1221. ;x=???432Xx
  1222. ;scraddr = %1xX????? ?????432
  1223.         ld bc,40 ;TODO в зависимости от переворота
  1224.        
  1225.         bit 5,(ix+2) ;attributes.behind
  1226.         jp nz,prcharxy_behind
  1227.        
  1228.         dup 7
  1229.         SHOWBYTE
  1230.         add hl,bc
  1231.         edup
  1232.         SHOWBYTE
  1233.        
  1234.         pop hl
  1235.         dup 7
  1236.         SHOWBYTE
  1237.         add hl,bc
  1238.         edup
  1239.         SHOWBYTE
  1240.        
  1241.         pop hl
  1242.         dup 7
  1243.         SHOWBYTE
  1244.         add hl,bc
  1245.         edup
  1246.         SHOWBYTE
  1247.        
  1248.         pop hl
  1249.         dup 7
  1250.         SHOWBYTE
  1251.         add hl,bc
  1252.         edup
  1253.         SHOWBYTE_LAST
  1254.         ;ret ;там уже есть
  1255.  
  1256. prcharxy_behind
  1257.         xor a
  1258.         dup 7
  1259.         SHOWBYTEBEHIND
  1260.         add hl,bc
  1261.         edup
  1262.         SHOWBYTEBEHIND
  1263.        
  1264.         pop hl
  1265.         dup 7
  1266.         SHOWBYTEBEHIND
  1267.         add hl,bc
  1268.         edup
  1269.         SHOWBYTEBEHIND
  1270.        
  1271.         pop hl
  1272.         dup 7
  1273.         SHOWBYTEBEHIND
  1274.         add hl,bc
  1275.         edup
  1276.         SHOWBYTEBEHIND
  1277.        
  1278.         pop hl
  1279.         dup 7
  1280.         SHOWBYTEBEHIND
  1281.         add hl,bc
  1282.         edup
  1283.         SHOWBYTEBEHIND_LAST
  1284.         ;ret ;там уже есть
  1285.  
  1286. EmulatePPU
  1287.         if FASTDEMOBEFOREBREAKPOINT
  1288.         ld a,0
  1289.         sub 4
  1290.         ld ($-1-2),a
  1291.          ;scf
  1292.         jr c,EmulatePPU_noskipgo
  1293. skipPPU=$
  1294.         ret
  1295. EmulatePPU_noskipgo    
  1296.         endif
  1297. ;ждать флаг ожидания готовности экрана (включается по прерыванию)
  1298. ;иначе будет так:
  1299. ;фрейм 1:
  1300. ;видим экран0, рисуем экран1
  1301. ;фрейм 2:
  1302. ;видим экран0, закончили рисовать экран1, [вот тут нужно ожидание], начали рисовать экран0 (хотя его видим)
  1303. ;фрейм 3:
  1304. ;видим экран1
  1305. ;готовность - это когда текущий таймер != таймер конца прошлой отрисовки
  1306. ;проверяем оба таймера, а то могло случиться системное прерывание
  1307. EmulatePPU_waitforscreenready0
  1308.         call gettimer
  1309. endoflastredrawtimer=$+1
  1310.         ld de,0
  1311.         or a
  1312.         sbc hl,de
  1313.         jr z,EmulatePPU_waitforscreenready0
  1314.  
  1315.         if OSCALLS
  1316. curpalette=$+1
  1317.         ld de,mariopal
  1318. oldpalette=$+1
  1319.         ld hl,0
  1320.         ld (oldpalette),de
  1321.         or a
  1322.         sbc hl,de
  1323.         jp z,EmulatePPU_nochpal ;реально поддержано изменение цвета Марио в палитре: при этом пишется oldpalette=левоечисло
  1324.         push de
  1325.         ;OS_GETTIMER ;dehl=timer
  1326.         ;ld (oldtimer),hl ;иначе yield вылетит без ожидания прерывания
  1327.         YIELD ;иначе можем напороться на di в swapimer
  1328.         call swapimer ;делать это после YIELD, т.к. внутри di..ei
  1329.         pop de
  1330.         OS_SETPAL ;на это время восстановлен обработчик прерываний, музыка выключена (а так надо посчитать, сколько прошло прерываний по системному таймеру и добавить в игровой таймер)
  1331.         YIELD ;иначе палитра не установится
  1332.         call swapimer
  1333.         else
  1334. EmulatePPU_nochpal
  1335.         endif
  1336.  
  1337.         call setpgs_scr
  1338.        
  1339. wascurkeyredraw=$+1
  1340.         ld a,0
  1341.         cp key_redraw
  1342.         if 1==1
  1343.         jr nz,EmulatePPU_nofullcls
  1344.         xor a
  1345.         ld (wascurkeyredraw),a
  1346.         ;ld hl,0x8000
  1347.         ;ld de,0x8000+1
  1348.         ;ld bc,0x7fff
  1349.         ;ld (hl),l;0
  1350.         ;ldir
  1351.         ld e,0
  1352.         OS_SETSCREEN
  1353.         ld e,0 ;color byte
  1354.         OS_CLS
  1355.         ld e,1
  1356.         OS_SETSCREEN
  1357.         ld e,0 ;color byte
  1358.         OS_CLS
  1359. EmulatePPU_nofullcls
  1360.         endif
  1361.         ld hl,0x8000+4+32
  1362.         call emppucls
  1363.         ld hl,0xa000+4+32
  1364.         call emppucls
  1365.         ld hl,0xc000+4+32
  1366.         call emppucls
  1367.         ld hl,0xe000+4+32
  1368.         call emppucls ;cls=173000
  1369.        
  1370.         ld hl,proc_endline
  1371.         ld (0),hl ;иначе системный обработчик прерываний успевает запортить (0x0001)
  1372.         call prtilesfast ;143700
  1373.  
  1374.         call setpgs_scr
  1375.         ;ld a,0x40
  1376.         ;ld (fonthsb),a
  1377. ;рисуем спрайты в обратном порядке (0-й на переднем плане)
  1378.         ld ix,Sprite_Data+256-4
  1379.         ;ld b,64;8
  1380. prsprites0
  1381.         ;push bc
  1382.         ld a,(ix) ;y
  1383.          sub 8*YSKIPFROMTOP
  1384.         cp 200-8
  1385.         jp nc,prsprites_skip ;большинство спрайтовых записей пустые, можно даже проверять на ==0xf8
  1386.         ld l,a ;y
  1387.  
  1388.         ld a,(ix+2) ;attributes
  1389.         rla ;flip vertically ;TODO программно
  1390. spritepage=$+1
  1391. spritepagemirhor=$+2
  1392.         ld bc,0
  1393.         jr nc,$+5
  1394. spritepagemirver=$+1
  1395. spritepagemirhorver=$+2
  1396.         ld bc,0
  1397.         rla ;flip horizontally
  1398.         ld a,c;
  1399.         jr nc,$+3
  1400.         ld a,b;mirver
  1401.          if RESTOREPG16K
  1402.          ;ld (curpg4000),a
  1403.          endif
  1404.         SETPG16K
  1405.        
  1406.         ld a,(ix+3) ;x
  1407.          inc a
  1408.          jr z,prsprites_skip ;почему-то прыжки на левой границе экрана в контакте с камнем дают x=0xff TODO
  1409.         srl a
  1410.         add a,4*4
  1411.        
  1412.         ld e,(ix+1) ;tile
  1413.         ld d,0x40 ;gfx
  1414.         ;ld l,e
  1415.         ;ld h,0x40/64
  1416.         ; add hl,hl
  1417.         ; add hl,hl
  1418.         ; add hl,hl
  1419.         ; add hl,hl
  1420.         ; add hl,hl
  1421.         ; add hl,hl
  1422.         ;ex de,hl
  1423. ;la=yx
  1424. ;de=gfx
  1425.         call prcharxy
  1426. prsprites_skip
  1427.         ;ld bc,-4
  1428.         ;add ix,bc
  1429.         ;pop bc
  1430.         ;djnz prsprites0
  1431.         ld a,lx
  1432.         sub 4
  1433.         ld lx,a
  1434.         jp nz,prsprites0 ;0-й спрайт - край монетки, можно не выводить
  1435.         ;jp nc,prsprites0
  1436.  
  1437.         ld a,1
  1438. curscreen=$+1
  1439.         xor 1
  1440.         ld (curscreen),a
  1441.         if OSCALLS
  1442.         ld e,a
  1443.         OS_SETSCREEN ;фактически включится по прерыванию ;первый отобразится 0-й экран
  1444.          ld a,e
  1445.         endif
  1446.          add a,a
  1447.          add a,a
  1448.          add a,a
  1449.          ld (imer_curscreen_value),a
  1450.          ;ld bc,0x7ffd
  1451.          ;out (c),a
  1452.  
  1453.         call gettimer
  1454.         ld (endoflastredrawtimer),hl
  1455.  
  1456. ;        ld hl,setpgs_scr_low
  1457. ;        ld a,(hl)
  1458. ;setpgs_scr_low_xor=$+1
  1459. ;        xor 2
  1460. ;        ld (hl),a
  1461. ;        ld hl,setpgs_scr_high
  1462. ;        ld a,(hl)
  1463. ;setpgs_scr_high_xor=$+1
  1464. ;        xor 2
  1465. ;        ld (hl),a
  1466.         ld hl,getuser_scr_low_patch
  1467.         ld a,(hl)
  1468.         xor getuser_scr_low_patchN
  1469.         ld (hl),a
  1470.         ld hl,getuser_scr_high_patch
  1471.         ld a,(hl)
  1472.         xor getuser_scr_high_patchN
  1473.         ld (hl),a
  1474.  
  1475.         call setpgs_code
  1476.         ld d,0
  1477.         ld b,d
  1478.         ret        
  1479.  
  1480. emppucls
  1481.         ld (emppuclssp),sp
  1482.         ld de,0
  1483.         ld bc,40
  1484.         ld a,200
  1485. emppucls0
  1486.         ld sp,hl ;во время прерывания de=0
  1487.         ld (hl),e
  1488.         dup 32/2
  1489.         push de
  1490.         edup
  1491.         add hl,bc
  1492.         dec a
  1493.         jr nz,emppucls0
  1494. emppuclssp=$+1
  1495.         ld sp,0
  1496.         ret
  1497.  
  1498.         include "nesconst.asm"
  1499.         include "smbconst.asm"
  1500.        
  1501. TitleScreen
  1502.         ds TitleScreenDataSize
  1503.  
  1504. prtilesfast
  1505.         call setpgaddrstack4000
  1506.         ld hl,0x2000 + (32*YSKIPFROMTOP)
  1507.         ld de,0x4000+6 ;addrstack
  1508.         ld bc,0x0280;0x0220
  1509.         call prtilesfast0block
  1510.        
  1511.          ld a,(Sprite0HitDetectFlag)
  1512.          or a
  1513.          ld c,0x80
  1514.          jr z,prtilesfastbottom ;no scroll
  1515.        
  1516.         ld a,(PPU_CTRL_REG1)
  1517.         rra
  1518.         jr nc,$+4
  1519.         set 2,h ;2nd tilemap
  1520.  
  1521.         ld a,(PPU_SCROLL_REG_H)
  1522.         rra
  1523.         ;rra
  1524.         ;rra
  1525.         and 127;31
  1526.         ld c,a ;scroll
  1527.         push hl
  1528.          srl a
  1529.          srl a
  1530.         add a,l
  1531.         ld l,a
  1532. ;будем выводить слева 32-scroll, справа scroll знакомест
  1533.        
  1534.         push bc
  1535.         push de ;screen (addrstack)
  1536.          ld a,c
  1537.          and 3
  1538.          jr z,prtilesfast_noblankleft
  1539.          dec de
  1540.          dec a
  1541.          jr nz,$-3
  1542. prtilesfast_noblankleft
  1543.         ld a,128;32
  1544.         sub c
  1545.         ld c,a
  1546.         ld b,25-2
  1547.         call prtilesfast0block
  1548.         pop de ;screen (addrstack)
  1549.         pop bc ;scroll
  1550.         pop hl
  1551.         ld a,h
  1552.         xor 4
  1553.         ld h,a ;another tilemap
  1554.         ;ld b,0
  1555.         ld a,128;32
  1556.         sub c
  1557.          ;add a,a
  1558.          ;add a,a
  1559.         add a,e
  1560.         ld e,a
  1561.         ;adc a,d
  1562.         ;sub e
  1563.         ;ld d,a
  1564.  
  1565. prtilesfastbottom
  1566.         ld b,25-2
  1567.         ld a,c
  1568.         or a
  1569.         ret z
  1570.        
  1571. ;для scroll phase 0 стек такой:
  1572. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1573. ;(scrR) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1574. ;для scroll phase 1 стек такой:
  1575. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1576. ;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2
  1577. ;для scroll phase 2 стек такой:
  1578. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1579. ;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1580. ;для scroll phase 3 стек такой:
  1581. ;(scrR) noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023
  1582. ;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1
  1583.        
  1584. ;генерируем один стек на все фазы (строки лежат через 256 байт):
  1585. ;noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr, noaddr
  1586. prtilesfast0block
  1587.         bit 0,e
  1588.         jr z,prtilesfast0block_even
  1589.          res 0,e
  1590.         push bc
  1591.         push de
  1592.         push hl
  1593.         push bc
  1594.         ;ld a,(setpgs_scr_high)
  1595.         call getuser_scr_high
  1596.         SETPG32KLOW
  1597.         call setpgtileprocL
  1598.         pop bc
  1599.         call prtilesfast0lines
  1600.         ;ld a,(setpgs_scr_low)
  1601.         call getuser_scr_low
  1602.         SETPG32KLOW
  1603.         call setpgtileprocR
  1604.         pop hl
  1605.         pop de
  1606.         pop bc
  1607.          inc de
  1608.          inc de
  1609.         jp prtilesfast0lines
  1610.  
  1611. prtilesfast0block_even
  1612.         push bc
  1613.         push de
  1614.         push hl
  1615.         push bc
  1616.         ;ld a,(setpgs_scr_low)
  1617.         call getuser_scr_low
  1618.         SETPG32KLOW
  1619.         call setpgtileprocL
  1620.         pop bc
  1621.         call prtilesfast0lines
  1622.         ;ld a,(setpgs_scr_high)
  1623.         call getuser_scr_high
  1624.         SETPG32KLOW
  1625.         call setpgtileprocR
  1626.         pop hl
  1627.         pop de
  1628.         pop bc
  1629.         ;call prtilesfast0
  1630.         ;ret
  1631.        
  1632. ;hl=tileaddr for line start
  1633. ;de=addrstack
  1634. ;b=hgt
  1635. ;c=width ;max 128
  1636. ;out: hl=tileaddr after last line, de=addrstack after last line
  1637. prtilesfast0lines
  1638.         ld hy,d
  1639.         ld ly,e ;iy=addrstack
  1640.         ld (prtilelinefast_sp),sp
  1641.         dec c
  1642.         srl c
  1643.         srl c
  1644.         inc c ;c=((width+3)/4)
  1645.         ld a,l
  1646.         add a,c ;без переноса, т.к. читаем тайлы через inc e
  1647.         ld l,a ;hl=tileaddr for line end
  1648. ;hl=tileaddr for line end
  1649. ;iy=addrstack
  1650. ;b=hgt
  1651. ;c=((width+3)/4)
  1652.         exx
  1653.         ld bc,40
  1654.         exx
  1655.         ld e,32
  1656. ;a=l
  1657.         ;jr $
  1658. _prtilesfast0
  1659.         ld sp,iy ;addrstack for this line
  1660.         inc hy ;addrstack for next line
  1661.         sub c ;без переноса, т.к. читаем тайлы через inc e
  1662.         ld d,(hl) ;old tile after last tile
  1663.         ld (hl),ENDLINETILE;0xfe ;patch after last tile
  1664.         exx
  1665.         ld e,a
  1666.         exx
  1667.         ld a,h
  1668.         exx
  1669.         ld d,a ;de=tileaddr for line start
  1670.         ld a,(de)
  1671.           ;inc e
  1672.         ld l,a
  1673.         or 0xc0
  1674.         ld h,a
  1675.         jp (hl)
  1676. proc_endline
  1677.         exx
  1678.         ld (hl),d ;unpatch after last tile
  1679.         ;add hl,de ;+32 (for next tileline) ;это надо делать для адреса начала строки, а адрес конца строки перекошен по HSB
  1680.          ld a,l
  1681.          sub c
  1682.          add a,e
  1683.          jp nc,$+4
  1684.          inc h
  1685.          add a,c
  1686.          ld l,a
  1687.         djnz _prtilesfast0
  1688. prtilelinefast_sp=$+1
  1689.         ld sp,0
  1690.         ld d,hy
  1691.         ld e,ly
  1692.         sub c ;без переноса, т.к. читаем тайлы через inc e
  1693.         ld l,a ;hl=tileaddr after last line
  1694.         ret
  1695.        
  1696. setpgaddrstack4000
  1697. pgaddrstack=$+1
  1698.         ld a,0
  1699.          if RESTOREPG16K
  1700.          ;ld (curpg4000),a
  1701.          endif
  1702.         SETPG16K
  1703.         ret
  1704. setpgaddrstackcopy4000 ;только в ините и int
  1705. pgaddrstackcopy=$+1
  1706.         ld a,0
  1707.         SETPG16K
  1708.         ret
  1709.  
  1710. setpgtileprocL
  1711. pgtileprocL=$+1
  1712.         ld a,0
  1713.         SETPG32KHIGH
  1714.         ret
  1715. setpgtileprocR
  1716. pgtileprocR=$+1
  1717.         ld a,0
  1718.         SETPG32KHIGH
  1719.         ret
  1720.  
  1721. shutay
  1722.         ld de,0xe00
  1723. shutay0
  1724.         dec d
  1725.         ld bc,0xfffd
  1726.         out (c),d
  1727.         ld b,0xbf
  1728.         out (c),e
  1729.         jr nz,shutay0
  1730.         ret
  1731.        
  1732.         if OSCALLS==0
  1733. oldpalette=$
  1734.         dw 0
  1735.         endif
  1736. on_int
  1737. ;if stack in 0x4000..0x7fff:
  1738. ;restore stack from pgaddrstackcopy (set in 0x4000 temporarily, then set pgaddrstack)
  1739. ;else restore stack with de;0
  1740.         ld (on_int_hl),hl
  1741.         ld (on_int_sp),sp
  1742.         ld (on_int_spcopy),sp
  1743.         pop hl
  1744.         ld (on_int_sp2),sp
  1745.         ld (on_int_jp),hl
  1746.         ld sp,INTSTACK
  1747.         push af
  1748.         push bc
  1749.         push de
  1750.  
  1751.         if RESTOREPG16K
  1752.         ld a,(curpg16k) ;ok
  1753.         push af
  1754.         endif
  1755.  
  1756. imer_curscreen_value=$+1
  1757.          ld a,0
  1758.          ld bc,0x7ffd
  1759.          out (c),a
  1760.  
  1761.         ld a,(on_int_sp+1)
  1762.         sub 0x40
  1763.         cp 0x3f ;запас, чтобы не захватить очистку экрана в 0x8000
  1764.         ex de,hl;ld hl,0
  1765.         jr nc,on_int_norestoredata
  1766.         ;jr $
  1767.         ld a,(pgaddrstackcopy)
  1768.         SETPG16K
  1769. on_int_spcopy=$+1
  1770.         ld hl,(0) ;ok
  1771.         ;if RESTOREPG16K==0
  1772.         ld a,(pgaddrstack)
  1773.         SETPG16K
  1774.         ;endif
  1775. on_int_norestoredata
  1776. on_int_sp=$+1
  1777.         ld (0),hl ;восстановили запоротый стек
  1778.  
  1779.         if MULTITASKING
  1780. ;        ld hl,on_int_q
  1781. ;intjpaddr=$+1
  1782. ;       ld (0),hl
  1783.         push ix
  1784.         push iy
  1785.         ex af,af'
  1786.        exx
  1787.        push af
  1788.        push bc
  1789.        push de
  1790.        push hl
  1791.        ld a,(curscreen)
  1792.        ld e,a
  1793.        OS_SETSCREEN ;вызываем здесь, а не в рандомном месте, иначе даже с одной задачей можем получить непредсказуемую задержку, которую не фиксирует наш таймер? с несколькими задачами надо учитывать и системный - TODO
  1794. curpalette=$+1
  1795.        ld de,mariopal
  1796.        OS_SETPAL
  1797.        
  1798.        GET_KEY
  1799.        cp key_redraw
  1800.        jr nz,$+5
  1801.        ld (wascurkeyredraw),a ;иначе не пишем
  1802.  
  1803.        pop hl
  1804.        pop de
  1805.        pop bc
  1806.        pop af
  1807.        exx
  1808.        ex af,af'
  1809.         pop iy
  1810.         pop ix
  1811.         endif
  1812.        
  1813.         if MULTITASKING==0 ;OSCALLS==0
  1814. curpalette=$+1
  1815.         ld de,mariopal
  1816.         ld hl,31
  1817.         add hl,de
  1818.         ld c,0xff
  1819.         ld a,7
  1820.         dup 8
  1821.         OUT (0xF6),A
  1822.         ld d,(hl)
  1823.         dec hl
  1824.         ld b,(hl) ;DDp palette low bits
  1825.         OUT (c),d;(0xFF),A
  1826.         dec hl
  1827.         dec a
  1828.         edup
  1829.         ld a,7
  1830.         dup 7
  1831.         OUT (0xFE),A
  1832.         ld d,(hl)
  1833.         dec hl
  1834.         ld b,(hl) ;DDp palette low bits
  1835.         OUT (c),d;(0xFF),A
  1836.         dec hl
  1837.         dec a
  1838.         edup
  1839.         OUT (0xFE),A ;0
  1840.         ld d,(hl)
  1841.         dec hl
  1842.         ld b,(hl) ;DDp palette low bits
  1843.         OUT (c),d;(0xFF),A
  1844.         endif
  1845.  
  1846.         ld hl,(curtimer)
  1847.         inc hl
  1848.         ld (curtimer),hl
  1849.  
  1850.         if MUSIC
  1851.         if MUSICONINT
  1852.         ld a,(codepage4000)
  1853.         SETPG16K
  1854.         ld b,0
  1855.         ld d,b
  1856. soundenginecall=$
  1857.         call SoundEngine
  1858.         endif
  1859.  
  1860.         ld c,0xfd
  1861.  
  1862.         if SWEEP
  1863. ;$4001(sq1)/$4005(sq2) bits
  1864. ;--------------------------
  1865. ;0-2    right shift amount
  1866. ;3      decrease / increase (1/0) wavelength
  1867. ;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
  1868. ;7      sweep enable
  1869. sweep1=$+1
  1870.         ld de,0 ;сколько бит в этом счётчике??? будем считать, что 8
  1871.         ld a,(SND_SQUARE1_REG+1)
  1872.         rra
  1873.         rra
  1874.         rra
  1875.         rra
  1876.         and 7 ;sweep rate
  1877.         inc a
  1878.         ld b,a
  1879. sweep1counter=$+1
  1880.         ld a,0
  1881.         sub 2 ;2 "sound frames"
  1882.         jr nc,$+3
  1883.         add a,b ;sweep rate
  1884.         ld (sweep1counter),a
  1885.         jr nc,sweep1noinc
  1886.         inc e
  1887.         ld (sweep1),de
  1888. sweep1noinc
  1889.         ld a,(SND_SQUARE1_REG+1)
  1890.         and 7 ;right shift
  1891.         jr z,sweep1noshift
  1892.         ld b,a
  1893. sweep1shift0
  1894.         srl e
  1895.         djnz sweep1shift0
  1896. sweep1noshift
  1897.         endif
  1898.  
  1899.         ld hl,SND_SQUARE1_REG+3
  1900.         ld a,(hl)
  1901.         dec hl
  1902.         ld l,(hl)
  1903.         and 7
  1904.         ld h,a
  1905.        
  1906.         if SWEEP
  1907.         ld a,(SND_SQUARE1_REG+1)
  1908.         or a
  1909.         jp p,sweep1disabled
  1910. ;add/sub sweep:
  1911.          scf ;for sq1 only!
  1912.         sbc hl,de
  1913.         and 8
  1914.         jr nz,$+5 ;decrease wavelength
  1915.          inc hl ;for sq1 only!
  1916.          add hl,de
  1917.          add hl,de ;increase wavelength
  1918. sweep1disabled
  1919.         endif
  1920.  
  1921.         ld a,1
  1922.         ld b,0xff
  1923.         out (c),a
  1924.         ld b,0xbf
  1925.         out (c),h
  1926.         dec a
  1927.         ld b,0xff
  1928.         out (c),a
  1929.         ld b,0xbf
  1930.         out (c),l
  1931.  
  1932.         if SWEEP
  1933. sweep2=$+1
  1934.         ld de,0 ;сколько бит в этом счётчике??? будем считать, что 8
  1935.         ld a,(SND_SQUARE2_REG+1)
  1936.         rra
  1937.         rra
  1938.         rra
  1939.         rra
  1940.         and 7 ;sweep rate
  1941.         inc a
  1942.         ld b,a
  1943. sweep2counter=$+1
  1944.         ld a,0
  1945.         sub 2 ;2 "sound frames"
  1946.         jr nc,$+3
  1947.         add a,b ;sweep rate
  1948.         ld (sweep2counter),a
  1949.         jr nc,sweep2noinc
  1950.         inc e
  1951.         ld (sweep2),de
  1952. sweep2noinc
  1953.         ld a,(SND_SQUARE2_REG+1)
  1954.         and 7 ;right shift
  1955.         jr z,sweep2noshift
  1956.         ld b,a
  1957. sweep2shift0
  1958.         srl e
  1959.         djnz sweep2shift0
  1960. sweep2noshift
  1961.         endif
  1962.  
  1963.         ld hl,SND_SQUARE2_REG+3
  1964.         ld a,(hl)
  1965.         dec hl
  1966.         ld l,(hl)
  1967.         and 7
  1968.         ld h,a
  1969.  
  1970.         if SWEEP
  1971.         ld a,(SND_SQUARE2_REG+1)
  1972.         or a
  1973.         jp p,sweep2disabled
  1974. ;add/sub sweep:
  1975.         sbc hl,de
  1976.         ld a,(SND_SQUARE2_REG+1)
  1977.         and 8
  1978.         jr nz,$+4 ;decrease wavelength
  1979.          add hl,de
  1980.          add hl,de ;increase wavelength
  1981. sweep2disabled
  1982.         endif
  1983.  
  1984.         ld a,5
  1985.         ld b,0xff
  1986.         out (c),a
  1987.         ld b,0xbf
  1988.         out (c),h
  1989.         dec a
  1990.         ld b,0xff
  1991.         out (c),a
  1992.         ld b,0xbf
  1993.         out (c),l
  1994.  
  1995.         ld d,0x0f ;all channels enabled
  1996.        
  1997.         ld a,11
  1998.         ld b,0xff
  1999.         out (c),a
  2000.         ld hl,SND_TRIANGLE_REG+3
  2001.         ld a,(hl)
  2002.         and 7
  2003.         dec hl
  2004.         ld e,(hl)
  2005.          sla e
  2006.          adc a,a
  2007.          jr z,$+2+2+2 ;иначе немного фальшивят верхние ноты в басу
  2008.           srl a
  2009.           rr e
  2010.          srl a
  2011.          rr e
  2012.          ld hl,curtimer
  2013.          bit 0,(hl)
  2014.          jr z,$+3
  2015.          inc e ;уседняем фальшь по 2 прерываниям
  2016.          srl a
  2017.          rr e
  2018.          jr nz,$+4
  2019.          res 1,d ;disable triangle if freq=0
  2020.         ld b,0xbf
  2021.         out (c),e
  2022.         ;ld e,12;3
  2023.         ;ld b,0xff
  2024.         ;out (c),e
  2025.         ;ld b,0xbf
  2026.         ;out (c),a
  2027.  
  2028.         ld a,6
  2029.         ld b,0xff
  2030.         out (c),a
  2031.         ld a,(SND_NOISE_REG+2)
  2032.         add a,a
  2033.         ld b,0xbf
  2034.         out (c),a
  2035.  
  2036. ;counters
  2037.         ld a,(SND_TRIANGLE_REG)
  2038.         or a
  2039.         jp m,trianglecount
  2040. ;linear counter load, stop length counter
  2041.         ;and 0x7f
  2042.         ld (trianglelinearcounter),a
  2043.         ;jp trianglehalt
  2044. trianglecount
  2045. trianglelinearcounter=$+1
  2046.         ld a,0
  2047.         sub 4
  2048.         jr nc,$+3
  2049.          xor a
  2050.         ld (trianglelinearcounter),a ;ld (SND_TRIANGLE_REG),a
  2051.         jr nz,$+4
  2052.         res 1,d ;triangle disabled because of linear counter=0
  2053.         ld a,(SND_COUNTER+8) ;(SND_TRIANGLE_REG+3) ;counter register, load it = f(SND_TRIANGLE_REG+3) at write there
  2054.         sub 1;2
  2055.         jr nc,$+3
  2056.         xor a
  2057.         ld (SND_COUNTER+8),a ;(SND_TRIANGLE_REG+3),a
  2058.         jr nz,$+4
  2059.         res 1,d ;triangle disabled because of counter=0
  2060. trianglehalt
  2061.  
  2062.         ld a,(SND_SQUARE2_REG)
  2063.         bit 5,a
  2064.         jp nz,square2halt ;counter disable
  2065.         ld a,(SND_COUNTER+4) ;(SND_SQUARE2_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+3) at write there
  2066.         sub 1;2
  2067.         jr nc,$+3
  2068.         xor a
  2069.         ld (SND_COUNTER+4),a ;(SND_SQUARE2_REG+3),a
  2070.         jr nz,$+4
  2071.         res 2,d ;disabled because of counter=0
  2072. square2halt
  2073.  
  2074.         ld a,(SND_SQUARE1_REG)
  2075.         bit 5,a
  2076.         jp nz,square1halt ;counter disable
  2077.         ld a,(SND_COUNTER+0) ;(SND_SQUARE1_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+1) at write there
  2078.         sub 1;2
  2079.         jr nc,$+3
  2080.         xor a
  2081.         ld (SND_COUNTER+0),a ;(SND_SQUARE1_REG+3),a
  2082.         jr nz,$+4
  2083.         res 0,d ;disabled because of counter=0
  2084. square1halt
  2085.  
  2086.         ld a,(SND_NOISE_REG)
  2087.         bit 5,a
  2088.         jp nz,noisehalt ;counter disable
  2089.         ld a,(SND_COUNTER+12) ;(SND_SQUARE1_REG+3) ;counter register, load it = f(SND_SQUARE2_REG+1) at write there
  2090.         sub 16;1;2
  2091.         jr nc,$+3
  2092.         xor a
  2093.         ld (SND_COUNTER+12),a ;(SND_SQUARE1_REG+3),a
  2094.         jr nz,$+4
  2095.         res 3,d ;disabled because of counter=0
  2096. noisehalt
  2097.  
  2098. ;channel enable
  2099.         ld a,7
  2100.         ld b,0xff
  2101.         out (c),a
  2102.         ld hl,SND_MASTERCTRL_REG ;%???DNT21
  2103.         ld a,(hl)
  2104.        if 1==1
  2105.         add a,0x2 ;%00? -> %01? (bit 2 reset), %11? -> %00? (bit 2 reset)
  2106.         and 0x4 ;was %00? or %11? - no swap
  2107.         ld a,(hl)
  2108.         jr z,noswap21 ;bit 2 reset - no swap
  2109.         xor 0x6 ;swap %01? <-> %10?
  2110. noswap21
  2111.        else
  2112.         rra ;%??????T?
  2113.         xor (hl)
  2114.         and 0x02
  2115.         xor (hl) ;%???DNTT1
  2116.         and 0xfb ;%???DN0T1
  2117.         bit 1,(hl)
  2118.         jr z,$+4
  2119.         or 0x04  ;%???DN2T1
  2120.        endif
  2121.        ;or 8 ;noise
  2122.         and d
  2123.         ld d,a
  2124.         cpl
  2125.         ;and 7
  2126.          and 5 ;enable B (тихая огибающая) ;or 2 ;disable triangle(B) here
  2127.         or 0x38 ;disable noise
  2128.          bit 3,d
  2129.          jr z,$+2+2+2
  2130.          set 1,a ;disable tone in B
  2131.          res 4,a ;enable noise in B
  2132.         ld b,0xbf
  2133.         out (c),a
  2134.  
  2135. ;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.
  2136. ;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).
  2137. ;vol
  2138.         ld e,8
  2139.         ld b,0xff
  2140.         out (c),e
  2141.         ld a,(SND_SQUARE1_REG) ;bit4=constant volume, or else envelope
  2142.         bit 4,a
  2143.         jr nz,vol1const
  2144.         ld a,(SND_DECAYVOL+0)
  2145. vol1const
  2146.         and 15
  2147.         ld hl,tvolume
  2148.         add a,l
  2149.         ld l,a
  2150.         adc a,h
  2151.         sub l
  2152.         ld h,a
  2153.         ld l,(hl)
  2154.         ld b,0xbf
  2155.         out (c),l
  2156.        
  2157.         ld hl,SND_SQUARE1_REG
  2158.         ld a,(hl)
  2159.         and 15 ;decay rate
  2160.         inc a
  2161.         ld b,a
  2162. vol1decaycounter=$+1
  2163.         ld a,0
  2164.         sub 4 ;4 "sound frames"
  2165.         jr nc,$+3
  2166.         add a,b ;decay rate
  2167.         ld (vol1decaycounter),a
  2168.         jr nc,vol1nodecay
  2169.          ld a,(SND_DECAYVOL+0)
  2170.          dec a
  2171.         jp p,vol1noenddecay
  2172.          and 0xf
  2173.         bit 5,(hl)
  2174.         jr nz,vol1noenddecay ;decay looping enabled
  2175.          xor a
  2176. vol1noenddecay
  2177.          ld (SND_DECAYVOL+0),a
  2178. vol1nodecay
  2179.  
  2180.         ld e,10
  2181.         ld b,0xff
  2182.         out (c),e
  2183.         ld a,(SND_SQUARE2_REG) ;bit4=constant volume, or else envelope
  2184.         bit 4,a
  2185.         jr nz,vol2const
  2186.         ld a,(SND_DECAYVOL+4)
  2187. vol2const
  2188.         and 15
  2189.         ld hl,tvolume
  2190.         add a,l
  2191.         ld l,a
  2192.         adc a,h
  2193.         sub l
  2194.         ld h,a
  2195.         ld l,(hl)
  2196.         ld b,0xbf
  2197.         out (c),l
  2198.        
  2199.         ld hl,SND_SQUARE2_REG
  2200.         ld a,(hl)
  2201.         and 15 ;decay rate
  2202.         inc a
  2203.         ld b,a
  2204. vol2decaycounter=$+1
  2205.         ld a,0
  2206.         sub 4 ;4 "sound frames"
  2207.         jr nc,$+3
  2208.         add a,b ;decay rate
  2209.         ld (vol2decaycounter),a
  2210.         jr nc,vol2nodecay
  2211.          ld a,(SND_DECAYVOL+4)
  2212.          dec a
  2213.         jp p,vol2noenddecay
  2214.          and 0xf
  2215.         bit 5,(hl)
  2216.         jr nz,vol2noenddecay ;decay looping enabled
  2217.          xor a
  2218. vol2noenddecay
  2219.          ld (SND_DECAYVOL+4),a
  2220. vol2nodecay
  2221.  
  2222.         ld e,9
  2223.         ld b,0xff
  2224.         out (c),e
  2225.         ld a,(SND_NOISE_REG) ;bit4=constant volume, or else envelope
  2226.         bit 4,a
  2227.         jr nz,noiseconst
  2228.         ld a,(SND_DECAYVOL+12)
  2229. noiseconst
  2230.         and 15
  2231.         ld hl,tvolume
  2232.         add a,l
  2233.         ld l,a
  2234.         adc a,h
  2235.         sub l
  2236.         ld h,a
  2237.         ld a,(hl)
  2238.         ;ld b,0xbf
  2239.         ;out (c),l
  2240.  
  2241.         ;ld e,9
  2242.         ;ld b,0xff
  2243.         ;out (c),e
  2244.          bit 3,d ;noise
  2245.          jr nz,notrianglevolumeout
  2246.         xor a
  2247.          bit 1,d ;triangle
  2248.          jr z,$+4
  2249.         ld a,16
  2250. notrianglevolumeout
  2251.         ld b,0xbf
  2252.         out (c),a
  2253.          ;and 15
  2254.          ;jr nz,$
  2255.        
  2256.         ld hl,SND_NOISE_REG
  2257.         ld a,(hl)
  2258.         and 15 ;decay rate
  2259.         inc a
  2260.         ld b,a
  2261. noisedecaycounter=$+1
  2262.         ld a,0
  2263.         sub 4 ;4 "sound frames"
  2264.         jr nc,$+3
  2265.         add a,b ;decay rate
  2266.         ld (noisedecaycounter),a
  2267.         jr nc,noisenodecay
  2268.          ld a,(SND_DECAYVOL+12)
  2269.          dec a
  2270.         jp p,noisenoenddecay
  2271.          and 0xf
  2272.         bit 5,(hl)
  2273.         jr nz,noisenoenddecay ;decay looping enabled
  2274.          xor a
  2275. noisenoenddecay
  2276.          ld (SND_DECAYVOL+12),a
  2277. noisenodecay
  2278.         endif
  2279.  
  2280.         if MULTITASKING
  2281.         call oldimer
  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. on_int_sp2=$+1
  2298.         ld sp,0
  2299.         ei
  2300. on_int_jp=$+1
  2301.         jp 0
  2302.  
  2303. SND_COUNTER
  2304. SND_DECAYVOL=$+1
  2305.         ds 4+4+4+2 ;sq1,sq2,tri,noise (2 bytes used from 4)
  2306.        
  2307. tvolume
  2308.         db 0,9,10,11, 12,12,13,13, 13,14,14,14, 15,15,15,15
  2309.        
  2310. ;что-то не так с этой таблицей
  2311. tcounterload
  2312.         db 0x7f,0x05
  2313.         db 0x01,0x0a
  2314.         db 0x02,0x14
  2315.         db 0x03,0x28
  2316.         db 0x04,0x50
  2317.         db 0x05,0x1e
  2318.         db 0x06,0x07
  2319.         db 0x07,0x0d
  2320.        
  2321.         db 0x08,0x06
  2322.         db 0x09,0x0c
  2323.         db 0x0a,0x18
  2324.         db 0x0b,0x30
  2325.         db 0x0c,0x60
  2326.         db 0x0d,0x24
  2327.         db 0x0e,0x08
  2328.         db 0x0f,0x10
  2329.        
  2330. gettimer
  2331. ;out: hl=timer
  2332. ;суммируем оба таймера - вдруг было системное прерывание
  2333.         if OSCALLS
  2334.         OS_GETTIMER ;dehl=timer
  2335. curtimer=$+1
  2336.         ld de,0
  2337.         add hl,de
  2338.         else
  2339. curtimer=$+1
  2340.         ld hl,0
  2341.         endif
  2342.         ret
  2343.  
  2344.         ;include "smbsound.asm"
  2345.         ;include "smbmusic.asm"
  2346.        
  2347. reservepage
  2348. ;new page, set page in textpages, npages++, set page in #c000
  2349. ;nz=error
  2350.         OS_NEWPAGE
  2351.         or a
  2352.         ret nz
  2353. npages=$+1
  2354.         ld hl,filepages
  2355.         ld (hl),e
  2356.         inc l
  2357.         ld (npages),hl
  2358.         ld a,e
  2359.         SETPG32KHIGH
  2360.         xor a
  2361.         ret ;z
  2362.        
  2363.  
  2364. DEMOLONGLINE=1
  2365.  
  2366. demooff
  2367. ;выключение демы, играем и пишем с клавиатуры
  2368.          ld a,55; ;scf ;201 ;ret
  2369.          ld (readdemo),a
  2370.          ;ld a,0x77
  2371.          ;ld (getbyte_opcode),a
  2372.          xor a
  2373.          ld (InjurePlayer_PiranhaPlant),a
  2374.          ;jp democontinue ;иначе будет вечная пауза
  2375. democontinue
  2376. ;продолжение после брякпоинта
  2377.         xor a
  2378.         ld (readdemo_stopflag),a
  2379.         ret
  2380.  
  2381.         macro NEXTBYTEFAST
  2382.         inc l
  2383.         call z,getbyte_inch_pp
  2384.         endm
  2385.         macro NEXTBYTEEND
  2386.         ld (getbyte_addr),hl
  2387.         endm
  2388.        
  2389. writedemo
  2390. ;сейчас указатель на разделителе после кнопок джойстика
  2391. ;a=keys
  2392. ;DEMOLONGLINE=1!!!
  2393.         push af
  2394.         call getbyte_setpg
  2395.         NEXTBYTEFAST
  2396.         ld (hl),'+'
  2397.        
  2398.         ld b,8
  2399. writedemo0
  2400.         NEXTBYTEFAST
  2401.         ld (hl),'.'
  2402.         djnz writedemo0
  2403.        
  2404.         NEXTBYTEFAST
  2405.         ld (hl),'|'
  2406.         NEXTBYTEFAST
  2407.         ld (hl),0x0d
  2408.         NEXTBYTEFAST
  2409.         ld (hl),0x0a
  2410.         NEXTBYTEFAST
  2411.         ld (hl),'|'
  2412.         NEXTBYTEFAST
  2413.         ld (hl),'.'
  2414.         NEXTBYTEFAST
  2415.         ld (hl),'.'
  2416.         NEXTBYTEFAST
  2417.         ld (hl),'|'
  2418.        
  2419.         pop af
  2420.         push af
  2421.         ld c,a
  2422.  
  2423.         if DEMOLONGLINE
  2424.         xor a
  2425.         ld b,c
  2426.         rr c
  2427.         rla
  2428.         rr c
  2429.         rla
  2430.         rr c
  2431.         rla
  2432.         rr c
  2433.         rla ;%0000UDLR
  2434.         xor b
  2435.         and 0x0f
  2436.         xor b
  2437.         ld c,a
  2438.         endif
  2439.  
  2440.         ld b,8
  2441. writedemo1
  2442.         NEXTBYTEFAST
  2443.         rrc c
  2444.         ld (hl),'.'
  2445.         jr nc,$+4
  2446.         ld (hl),'Z'
  2447.         djnz writedemo1
  2448.        
  2449.         NEXTBYTEEND
  2450.  
  2451.         call setpgs_code
  2452.         pop af
  2453.         ret
  2454.  
  2455. readdemo
  2456.         display "readdemo=",$
  2457.         or a ;/scf
  2458.         jr c,writedemo
  2459. readdemo_stopflag=$
  2460.         nop ;/ret
  2461.  
  2462.         ;jr $
  2463.         call getbyte_setpg
  2464.        
  2465.         if 1==0 ;однобайтный формат дем
  2466.         ld a,(hl)
  2467. ;a=buttons = %R?D?t?BA
  2468.         ld b,8
  2469.         rra
  2470.         rl c
  2471.         djnz $-3
  2472.         NEXTBYTEEND
  2473.         ld a,c
  2474.        
  2475. ;a=buttons
  2476. ;bit - button (ZX key)
  2477. ;7 - A (A)
  2478. ;6 - B (S)
  2479. ;5 - Select (Space)
  2480. ;4 - Start (Enter)
  2481. ;3 - Up (7)
  2482. ;2 - Down (6)
  2483. ;1 - Left (5)
  2484. ;0 - Right (8)
  2485.         else
  2486.        
  2487. ;"|0|RLDUTsBA|||",0x0a = 15 bytes, реально начинаем на 4 байта раньше
  2488. ;"|.r|UDLRSsBA|........|",0x0d,0x0a = 24 bytes, реально начинаем на 12 байт раньше
  2489. ;лучше перейти на короткий формат, а то 6000t после оптимизации (один байт = 194t)
  2490.         if DEMOLONGLINE
  2491.         ld d,12+4
  2492.         else
  2493.         ld d,3+4
  2494.         endif
  2495.        
  2496. readdemo0
  2497.         NEXTBYTEFAST
  2498.         ld a,(hl)
  2499.         add a,256-'A'
  2500.         rr e
  2501.         dec d
  2502.         jp nz,readdemo0
  2503.  
  2504.         ld d,0x80
  2505. readdemo1
  2506.         NEXTBYTEFAST
  2507.         ld a,(hl)
  2508.         add a,256-'A'
  2509.         rr d
  2510.         jp nc,readdemo1
  2511.        
  2512.         NEXTBYTEEND
  2513.        
  2514.         if DEMOLONGLINE
  2515.          ;ld a,e
  2516.          ;and 0x40 ;reset
  2517.          ;cp 0
  2518.          ;ld ($-1),a
  2519.         bit 6,e
  2520.          jp z,readdemo_noreset
  2521.         ;or a
  2522.         ;jr nz,readdemo_noreset
  2523.         ;pop af
  2524.         ;jp Start
  2525.         if FASTDEMOBEFOREBREAKPOINT
  2526.         push de
  2527.         xor a
  2528.         ld (skipPPU),a
  2529.         call EmulatePPU
  2530.         call EmulatePPU
  2531.         pop de
  2532.         endif
  2533.         ld a,201
  2534.         ld (readdemo_stopflag),a
  2535. readdemo_noreset
  2536.  
  2537.         xor a
  2538.         ld b,d
  2539.         rr d
  2540.         rla
  2541.         rr d
  2542.         rla
  2543.         rr d
  2544.         rla
  2545.         rr d
  2546.         rla ;%0000UDLR
  2547.         xor b
  2548.         and 0x0f
  2549.         xor b
  2550.        
  2551.         else
  2552.        
  2553.         ld a,d
  2554.        
  2555.         endif
  2556.        
  2557.         endif
  2558. ;a=buttons
  2559. ;bit - button (ZX key)
  2560. ;7 - A (A)
  2561. ;6 - B (S)
  2562. ;5 - Select (Space)
  2563. ;4 - Start (Enter)
  2564. ;3 - Up (7)
  2565. ;2 - Down (6)
  2566. ;1 - Left (5)
  2567. ;0 - Right (8)
  2568.         push af
  2569.         call setpgs_code
  2570.         pop af
  2571.         ret
  2572.        
  2573. getbyte_setpg
  2574. ;портит hl,bc
  2575. ;не портит de
  2576. ;out: a=pg, hl=addr in pg
  2577. getbyte_addr=$+1 ;реально читать начнём со следующего адреса
  2578.         ;ld hl,0xffe0+5 ;148974
  2579. ;правдоподобно только 5..6, что-то не так с отскоком от врага?
  2580.         ;ld hl,0xffe0+14 ;53672
  2581.         ;ld hl,0xc260+4 ;53672
  2582. ;было (когда старт нажимался слишком поздно - уже во встроенной деме)
  2583. ;12..13 проход через трубу медленно, сдох на монстре
  2584. ;14 (+4) проход через трубу с задержкой справа, потом застрял на лестнице
  2585. ;15 не допрыгнул до трубы с бонусом
  2586. ;16-20 ещё хуже
  2587.         ;ld hl,0xd2c8-12-1+(15*24) ;1904330 (pg1)
  2588. ;11..13 сбил кирпич, пропрыгал две трубы
  2589. ;14 прошёл 1-1, сдох на черепахе в 1-2
  2590. ;15 прошёл 1-1, сдох на грибе после черепахи в 1-2
  2591. ;16 нырнул в трубу, но не собрал монетки, а застрял
  2592. ;17..20 не стартует
  2593.         ;ld hl,0xc111-4-1+(16*15) ;351918
  2594. ;11..14 - застреваем после убийства второго монстра
  2595. ;15 - перепрыгиваем его, застреваем дальше
  2596. ;16 - пролезаем через трубу, застреваем на лестнице
  2597. ;17..20- умираем на втором монстре
  2598.         ;ld hl,0xc0f4-4-1+(7*15) ;307549
  2599. ;7..8 - довольно быстро бежим, но попадаем на первого монстра
  2600. ;9 прыжок явно мимо
  2601. ;12 медленно
  2602. ;16..20 не стартует
  2603.         ld hl,0xc090-12-1 +(4*24) ;1775978 (cropped)
  2604. ;0,1 - проходим world 1-1 (при jr RImpd застреваем возле замка)
  2605. ;2,3 - застреваем на конечной лестнице 1-1 (при jr RImpd застреваем в трубе)
  2606. ;4 - доходим дальше в 1-2 (при jr RImpd застреваем возле замка)
  2607. ;5,6,7,8,9,10,11,12,13,14,15,16,17,18 - не проходим 1-1 (18 при jr RImpd застреваем возле замка)
  2608. ;19,20 - застреваем на конечной лестнице 1-1 (при jr RImpd застреваем возле замка)
  2609. ;21,22 - проходим world 1-1
  2610. ;23,24 - застреваем на конечной лестнице 1-1
  2611. ;25 - доходим дальше в 1-2
  2612. getbyte_pg=$+1
  2613.         ld a,(filepages)
  2614.         SETPG32KHIGH
  2615.         ret
  2616.        
  2617. getbyte_inch_pp
  2618. ;не портит bc, переустанавливает hl в начале новой страницы (тогда же щёлкает страницу)
  2619. ;l=0
  2620.         inc h
  2621.         ret nz
  2622.          ld hl,getbyte_pg
  2623.          inc (hl)
  2624.         push bc
  2625. getbyte_inch_memoryretry_m
  2626.         ld c,(hl)
  2627.         ld b,filepages/256
  2628. getbyte_inch_memoryretry
  2629.         ld a,(bc)
  2630.         or a
  2631.         jr z,getbyte_inch_newpg
  2632.         SETPG32KHIGH
  2633.         pop bc
  2634.          ld hl,0xc000
  2635.         ret
  2636. getbyte_inch_newpg
  2637.          push bc
  2638.          push de
  2639.           halt ;чтобы не сработало системное прерывание
  2640.          call reservepage ;nz=error ;портит все регистры (но нам hl не важен)
  2641.           ld a,(imer_curscreen_value)
  2642.           ld bc,0x7ffd
  2643.           out (c),a
  2644.          pop de
  2645.          pop bc
  2646.          jr z,getbyte_inch_memoryretry
  2647.          ld hl,getbyte_pg
  2648.          dec (hl)
  2649.         jr getbyte_inch_memoryretry_m ;no more memory
  2650.        
  2651.  
  2652. savedemo
  2653.         ld de,filename2
  2654.         OS_CREATEHANDLE
  2655. ;b=new file handle
  2656.         push af
  2657.         ld a,b
  2658.         ld (filehandle),a
  2659.         pop af
  2660.         ;or a
  2661.         ;ret nz
  2662.        
  2663.         ld hl,0
  2664.         ld de,0
  2665.         ld a,0
  2666. nvview_save0
  2667.         ;push de
  2668.         ;push hl
  2669.         ;call reservepage
  2670.         ;pop hl
  2671.         ;pop de
  2672.         ;ret nz ;no memory
  2673.         push af
  2674.         ld c,a
  2675.         ld b,filepages/256
  2676.         ld a,(bc)
  2677.         SETPG32KHIGH
  2678.        
  2679.         push de
  2680.         push hl
  2681.         ld de,0xc000
  2682.         ld hl,0x4000
  2683. ;DE = Buffer address, HL = Number of bytes to read
  2684.         push hl
  2685.         ld a,(filehandle)
  2686.         ld b,a
  2687.         OS_WRITEHANDLE
  2688. ;hl=actual size
  2689. ;hl=loaded bytes
  2690.         ld b,h
  2691.         ld c,l
  2692.         pop hl ;Number of bytes to read
  2693.         or a
  2694.         sbc hl,bc ;z=loaded as requested
  2695. ;bc=loaded bytes
  2696.         pop hl
  2697.         pop de
  2698.         pop af
  2699. ;hlde=size
  2700. ;z=loaded as requested
  2701.         ;ex de,hl
  2702.         ;add hl,bc
  2703.         ;ex de,hl
  2704.         ;jr nc,$+3
  2705.         ;inc hl
  2706.         ;jr z,nvview_save0
  2707.         inc a
  2708.         ld ix,npages
  2709.         cp (ix)
  2710.         jr nz,nvview_save0
  2711. ;hlde=true file size (for TRDOSFS)
  2712.         ;ld (fcb+FCB_FSIZE),de
  2713.         ;ld (fcb+FCB_FSIZE+2),hl
  2714.  
  2715.         call closestream_file
  2716.         jp setpgs_code
  2717.  
  2718. gfxfilename
  2719.         db "smb.nes",0
  2720. filename
  2721.         db "antipac.fm2",0
  2722. filename2
  2723.         db "demo.fm2",0
  2724.         include "../../_sdk/file.asm"
  2725. tnofile
  2726.         db "smb.nes not found",0x0d,0x0a,0
  2727.  
  2728. ;oldtimer
  2729. ;       ds 2
  2730.  
  2731.         ;display "free before 0x2000=",0x2000-$
  2732.         ds 0x2000-$
  2733. ;tile gfx: 2 256-tile maps
  2734. ;16bytes/tile: 8bytes low bit, 8bytes high bit
  2735. tilegfx
  2736.         ds 0x2000 ;incbin "smbtiles"
  2737.        
  2738.         include "SMBDIS.ASM"
  2739.  
  2740. end
  2741.  
  2742.         ;display "End=",end
  2743.         ;display "Free after end=",/d,0xc000-end
  2744.         ;display "Size ",/d,end-begin," bytes"
  2745.        
  2746.         savebin "smb.com",begin,end-begin
  2747.        
  2748.         ;LABELSLIST "user.l"
  2749.