Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

        DEVICE ZXSPECTRUM128
        include "../../_sdk/sys_h.asm"
;│┐│-│-TПTВTМ:
;0x0100..0x3eff - subroutines
;0x3f00..0x3fff - stack
;0x4000..0x7fff - VRAM
;0x8000..0xbfff - game/paged for screen
;0xc000..0xffff - scratchpad RAM/paged for screen

INTSTACK=0x0100;0x3f00
STACK=INTSTACK-64

        org PROGSTART
begin
        ld sp,STACK
        OS_HIDEFROMPARENT

        ld e,0 ;EGA
        OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)

        ld e,0
        OS_SETSCREEN
        ld e,0 ;color byte
        OS_CLS
        ld e,1
        OS_SETSCREEN
        ld e,0 ;color byte
        OS_CLS

        OS_GETMAINPAGES
;dehl=pages in 0000,4000,8000,c000
        ld a,e
        ld (pgcode4000),a
        ld a,h
        ld (pgcode8000),a
        ld a,l
        ld (pgcodec000),a

        ld a,e
        ld hl,MUZHOOK
        OS_SETMUSIC

        OS_NEWPAGE
        ld a,e
        ld (pgtiles),a

        ld de,pal
        OS_SETPAL

        call swapimer

        jp GO

pal
;DDp palette: %grbG11RB(low),%grbG11RB(high), inverted
                   ;bg=1  ;зел  ;салат  ;син  ;небо  ;крас  ;ярко-голуб
        dw 0xffff,0xffff,0xcfcf,0x4f4f,0xdede,0xcccc,0xfdfd,0xcece
        dw 0xbdbd,0xacac,0x2d2d,0x2c2c,0xefef,0x4e4e,0xecec,0x0c0c
           ;флаг  ;роз   ;древко ;лим  ;тзел  ;???    ;road
timer
        dw 0
oldtimer
        dw 0
quiter
        halt
        ;ld a,(pgmuznum)
        ;SETPG32KHIGH
        ;call muz
        call shutay
        call swapimer
        QUIT


swapimer
        di
        ld de,0x0038
        ld hl,oldimer
        ld bc,3
swapimer0
        ld a,(de)
        ldi ;[oldimer] -> [0x0038]
        dec hl
        ld (hl),a ;[0x0038] -> [oldimer]
        inc hl
        jp pe,swapimer0
        ei
        ret
oldimer
        jp on_int ;заменится на код из 0x0038
        jp 0x0038+3

on_int
;restore stack with de
        ld (on_int_hl),hl
        ld (on_int_sp),sp
        pop hl
        ld (on_int_sp2),sp
        ld (on_int_jp),hl
       
        ld sp,INTSTACK
       
        push af
        push bc
        push de
       
;imer_curscreen_value=$+1
         ;ld a,0
         ;ld bc,0x7ffd
         ;out (c),a

        ex de,hl;ld hl,0
on_int_sp=$+1
        ld (0),hl ;восстановили запоротый стек
       
        push ix
        push iy
        ex af,af' ;'
        exx
        push af
        push bc
        push de
        push hl
;curpalette=$+1
        ;ld de,wolfpal
        ;OS_SETPAL

curscrnum_int=$+1
        ld e,0
        OS_SETSCREEN
       
;pgmuznum=$+1
;        ld a,0
;        SETPG32KHIGH
       
         call oldimer
       
        GET_KEY
        ld (curkey),a
        if 1==0
        ld a,(curpg32klow) ;ok
        push af
        ld a,(curpg32khigh) ;ok
        push af
        call setpgcode8000c000
        call MUZHOOK ;muzplay
        pop af
        SETPG32KHIGH
        pop af
        SETPG32KLOW
;pgc000=$+1
;        ld a,0
;        SETPG32KHIGH
        endif
       
        pop hl
        pop de
        pop bc
        pop af
        exx
        ex af,af' ;'
        pop iy
        pop ix
       
        ld hl,(timer)
        inc hl
        ld (timer),hl

        pop de
        pop bc
        pop af
       
on_int_hl=$+1
        ld hl,0
on_int_sp2=$+1
        ld sp,0
        ei
on_int_jp=$+1
        jp 0

setpgtiles4000
pgtiles=$+1
        ld a,0
        SETPG16K
        ret

setpgtiles8000
        ld a,(pgtiles)
        SETPG32KLOW
        ret

setpgcode4000
pgcode4000=$+1
        ld a,0
        SETPG16K
        ret

setpgcode8000c000
pgcode8000=$+1
        ld a,0
        SETPG32KLOW
pgcodec000=$+1
        ld a,0
        SETPG32KHIGH
        ret
 
gentiles
        ;call setpgtiles4000

        ld l,0
gentiles0
        ld h,0x20
        ld d,0x40/8
        ld a,l
        add a,a
        rl d
        add a,a
        rl d
        add a,a
        rl d
        ld e,a
        dup 8
        ld a,(de)
         ld (hl),-1;0
         rla
         rr (hl)
         rla
         rr (hl)
        set 3,h
         ld (hl),-1;0
         rla
         rr (hl)
         rla
         rr (hl)
        res 3,h
        set 4,h
         ld (hl),-1;0
         rla
         rr (hl)
         rla
         rr (hl)
        set 3,h
         ld (hl),-1;0
         rla
         rr (hl)
         rla
         rr (hl)        
        res 3,h
        res 4,h
        inc e
        inc h
        edup
       
        ld h,0x20
gentiles0atr0
        ld d,0x60/8
        ld a,l
        add a,a
        rl d
        add a,a
        rl d
        add a,a
        rl d
        xor h
        and 0xf8
        xor h
        ld e,a
        ld a,(de) ;IiiiPppp
        rra
        rra
        rra
        rra
        call geninkbyte
        ld c,a
        ld a,(de)
        call geninkbyte
        ld b,a
        ;ld bc,0b0000000011111111
;c=ink (IIiiiiii)
;b=paper (PPpppppp)
        ld a,(hl)
        rla
        sbc a,a
        ld e,a ;RRRRRRRR
        ld a,(hl)
        rla
        rla
        sbc a,a ;LLLLLLLL
        xor e
        and 0b01000111
        xor e
        ld d,a
;a=%RLRRRLLL        
        and c ;ink (IIiiiiii)
        ld e,a
        ld a,d
        cpl
        and b ;paper (PPpppppp)
        or e
        ld (hl),a
        inc h
        bit 6,h
        jr z,gentiles0atr0
       
        inc l
        jp nz,gentiles0

        ;call setpgcode4000
;gen sprites
;The Sprite Pattern Table occupies 2 KB of VRAM from 3800H to 3FFFH. It contains two hundred and fifty-six 8x8 pixel patterns, numbered from 0 to 255.
;AC
;BD
;8 bytes block A
;8 bytes block B
;8 bytes block C
;8 bytes block D
;pattern 0..3 = pattern 0, pattern 4..7 = pattern 1...
;(decoded to 128 bytes per pattern in pgtiles)
        call setpgtiles8000

        ld hl,0x4000+0x1800
        ld de,0x8000

        ld b,2*64 ;halfsprites
genspr0
        push bc
       
        ld ix,0b0100000010000000
        ld a,b
        cp 2*64-7
        jr nc,$+2+4
        ld ix,0b0100011110111000
       
        ld c,4
genspr0subcolumns
        push hl
        ld b,16
genspr00
;colors:
;0b1110 - road  (and 0b1111)
;0b0001?- shadow
;0b0110 -our car(and 0b0111)
;0b0000 - enemy (and 0b0000)
        ld a,0xff
        rlc (hl)
        jr nc,$+4
        xor hx;0b01000000 ;change left pixel
        rlc (hl)
        jr nc,$+4
        xor lx;0b10000000 ;change right pixel
        ld (de),a
        inc hl
        inc de
        djnz genspr00
        pop hl
        dec c
        jr nz,genspr0subcolumns
        ld bc,16
        add hl,bc ;next column (halfsprite)
        pop bc
        djnz genspr0
       
        call setpgcode8000c000

        ret

geninkbyte
;a=????Iiii
;out: a=IIiiiiii
        ld b,a
        rla
        rla
        rla
        xor b
        and 0b01111000
        xor b ;?Iiiiiii
        rla   ;Iiiiiii?
        rlca  ;iiiiii?I
        rra   ;Iiiiiii? (CY=I)
        rra
        ret

;0 чёрный
;1 чёрный
;2 тёмно-зелёный с синевой
;3 ярко-зелёный
;4 синий
;5 фиолетовый
;6 красный
;7 тёмно-голубой
;8 ярко-красный
;9 розовый
;a ярко-жёлтый
;b лимонный
;c тёмно-зелёный
;d ярко-голубой
;e серый (дорога)
;f белый
        MACRO SPRCOLUMN
       dup 15
        ld a,(de)
        and (hl)
        ld (hl),a;0xaa
        inc e
        add hl,bc ;40
       edup
        ld a,(de)
        and (hl)
        ld (hl),a;0xaa
        inc e
        endm

        macro NEXTCOLUMN
        bit 6,h
        set 6,h
        jr z,$+2+4+2+2+1
        ld a,h
        xor 0x60
        ld h,a
        and 0x20
        jr nz,$+3
        inc hl
        endm

;The Name Table occupies 768 bytes of VRAM from 1800H to 1AFFH (!!!3800!!!), the same as in 32x24 Text Mode. The table is initialized with the character code sequence 0 to 255 repeated three times and is then left untouched, in this mode it is the Character Pattern Table which is modified during normal operation.

;The Character Pattern Table occupies 6 KB of VRAM from 0000H to 17FFH. While its structure is the same as in the text modes it does not contain a character set but is initialized to all 0 pixels. The first 2 KB of the Character Pattern Table is addressed by the character codes from the first third of the Name Table, the second 2 KB by the central third of the Name Table and the last 2 KB by the final third of the Name Table. Because of the sequential pattern in the Name Table the entire Character Pattern Table is read out linearly during a video frame.

emulVDP
        push bc
        push de
        push hl
curkey=$+1
        ld a,0
        cp key_esc
        jp z,quiter
;wait for screen change
EmulatePPU_waitforscreenready0
        ld hl,(timer)
endoflastredrawtimer=$+1
        ld de,0
        or a
        sbc hl,de
        jr z,EmulatePPU_waitforscreenready0

        ;ld a,(user_scr0_low) ;ok
        ;SETPG32KLOW
        ;ld a,(user_scr0_high) ;ok
        ;SETPG32KHIGH
        call setpgsscr8000c000
;TODO draw only changed tiles
        ld de,0x4000+0x3800 ;tilemap
        ld hl,0x8000+4 ;screen
        ;ld hx,0x40 ;tile gfx base
        ld b,24
emulVDPtiles0
        push bc
        ld a,24
        sub b
        rra
        rra
        rra
        and 3
        add a,0x40/8
        ld hx,a ;tile gfx base
        push hl
        ld b,32
emulVDPtiles1
        ld a,(de) ;tile
        push bc
        push de
        push hl
       
        ld bc,40
       
        ld e,a
       
        push hl
       
        ld d,0x20
        push hl
        dup 7
        ld a,(de)
        ld (hl),a
        inc d
        add hl,bc
        edup
        ld a,(de)
        ld (hl),a
        pop hl
       
        set 6,h
       
        ld d,0x28
        dup 7
        ld a,(de)
        ld (hl),a
        inc d
        add hl,bc
        edup
        ld a,(de)
        ld (hl),a
       
        pop hl
        set 5,h
       
        ld d,0x30
        push hl
        dup 7
        ld a,(de)
        ld (hl),a
        inc d
        add hl,bc
        edup
        ld a,(de)
        ld (hl),a
        pop hl
       
        set 6,h
       
        ld d,0x38
        dup 7
        ld a,(de)
        ld (hl),a
        inc d
        add hl,bc
        edup
        ld a,(de)
        ld (hl),a
       
        pop hl
        pop de
        pop bc
        inc de
        inc hl
        dec b
        jp nz,emulVDPtiles1
        pop hl
        ld bc,40*8
        add hl,bc
        pop bc
        dec b
        jp nz,emulVDPtiles0
       
;The Sprite Attribute Table occupies 128 bytes of VRAM from 1B00H to 1B7FH /3b00/. The table contains thirty-two four byte blocks, one for each sprite. The first block controls sprite 0 (the "top" sprite), the ;second controls sprite 1 and so on to sprite 31. The format of each block is as below:

;   Vertical Position   Byte 0
;   Horizontal Position Byte 1
;   Pattern Number      Byte 2
;   EC  0       0       0       Colour Code(bits 3..0)  Byte 3
;In Byte 3, the Early Clock bit is normally 0 but will shift the sprite thirty-two pixels to the left when set to 1. This is so that sprites can slide in from the left of the screen, there being no spare coordinates in the horizontal direction.    

;The Sprite Pattern Table occupies 2 KB of VRAM from 3800H to 3FFFH /1800/. It contains two hundred and fifty-six 8x8 pixel patterns, numbered from 0 to 255.
;AC
;BD
;8 bytes block A
;8 bytes block B
;8 bytes block C
;8 bytes block D
;for 16x16 sprites: pattern 0..3 = pattern 0, pattern 4..7 = pattern 1...
        ld hl,0x4000+0x3B7F
emulVDPsprites0
        ld a,(hl) ;d3..0=colour code, d7=early clock (x-=32)
        dec l
        ld d,(hl) ;pattern number
        dec l
        ld c,(hl) ;x
        dec l
        ld b,(hl) ;y
        or a
        jp z,emulVDPsprites0_skip ;colour 0
          inc b
        ld a,b
        cp 0xd1+1 ;???
        jp nc,emulVDPsprites0_skip
          inc c
         srl c
         srl c
         srl c
         ld a,c
         add a,4
         ld c,a
         ;srl b
         ;srl b
         ;srl b
         ld a,b
         cp 24 *8
         jp nc,emulVDPsprites0_skip
        push hl
;bc=yx
        ld a,c ;x
        ld l,b ;y
        ld h,0
        ld b,h
        ld c,l
        add hl,hl
        add hl,hl
        add hl,bc ;*5
         add hl,hl
         add hl,hl
         add hl,hl ;*40
         ;add hl,hl
         ;add hl,hl
         ;add hl,hl
        add a,l
        ld l,a
        ld a,h
        adc a,0x80
        ld h,a

        call setpgtiles4000

        ld bc,40
;d=pattern number
        ld e,0
         srl d
         srl d ;pattern 0..3 = pattern 0, pattern 4..7 = pattern 1...
        srl d
        rr e
        set 6,d ;ld d,0x40;+0x38 ;sprites
        dup 8-1
        push hl
        SPRCOLUMN
        pop hl
        NEXTCOLUMN
        edup
        SPRCOLUMN
       
        call setpgcode4000
       
        pop hl
emulVDPsprites0_skip
        dec l
        jp p,emulVDPsprites0

        ld hl,(timer)
        ld (endoflastredrawtimer),hl
        call changescrpg
       
        call setpgcode8000c000
        pop hl
        pop de
        pop bc
        ret
 
pause
        push af
        push bc
        push de
        push hl
        exx
        ex af,af' ;'
        push af
        push bc
        push de
        push hl
        push ix
        push iy
        halt ;YIELD
        pop iy
        pop ix
        pop hl
        pop de
        pop bc
        pop af
        ex af,af' ;'
        exx
        pop hl
        pop de
        pop bc
        pop af
        ret

muztest
        ei
        halt
        call L_9266 ;music player
        jr muztest

L0020
;DCOMPR
;Address  : #0020
;Function : Compares HL with DE
;Input    : HL, DE
;Output   : Z-flag set if HL and DE are equal. C-flag set if HL is less than DE.
;Registers: AF
        push hl
        or a
        sbc hl,de
        pop hl
        ret

L003D
;???
;INIFNK
;Address  : #003E
;Function : Initialises the contents of the function keys
;Registers: All
        ret

L0047        
;WRTVDP
;Address  : #0047
;Function : write data in the VDP-register
;Input    : B  - data to write
;           C  - number of the register
;Registers: AF, BC
;can spoil bc
;TODO
        ret
       
L004D
;WRTVRM
;Address  : #004D
;Function : Writes data in VRAM
;Input    : HL - address write (0..3fff)
;           A  - value write
;Registers: AF
        push hl
        set 6,h
        ld (hl),a
        pop hl
        ret
       
L0056
;FILVRM
;Address  : #0056
;Function : fill VRAM with value
;Input    : A  - data byte
;           BC - length of the area to be written
;           HL - start address
;Registers: AF, BC
        push bc
        push hl
        set 6,h
FILVRM0
        ld (hl),a
        cpi
        jp pe,FILVRM0
        pop hl
        pop bc ;unneeded?
        ret

L005C        
;LDIRVM
;Address  : #005C
;Function : Block transfer to VRAM from memory
;Input    : BC - blocklength
;           DE - Start address of VRAM
;           HL - Start address of memory
;Registers: All
        push bc
        push de
        push hl
        set 6,d
        ldir
        pop hl
        pop de
        pop bc ;unneeded?
        ret
       
L00D5
;GTSTCK
;Address  : #00D5
;Function : Returns the joystick status
;Input    : A  - Joystick number to test (0 = cursors, 1 = port 1, 2 = port 2)
;Output   : A  - Direction (1 up, 3 right, 5 down, 7 left)
;Registers: All
        or a
        jp nz,GTSTCK2
         push bc
         ld a,0x7f
         in a,(0xfe)
         bit 2,a ;'M'
         jr nz,nomuzoff
         ld a,(muzoff)
         xor 0x80
         ld (muzoff),a
         push de
         push hl
         push ix
        LD      A,#07
        CALL    L0096
        AND     #C0
        OR      #38
        LD      E,A
        LD      A,#07
        CALL    L0093
        LD      E,#0e
        LD      A,#08
        CALL    L0093
        LD      A,#0a
        CALL    L0093
        halt
        halt
        halt
         pop ix
         pop hl
         pop de
nomuzoff
         ld a,0xfe
         in a,(0xfe)
         bit 0,a
         jr nz,nocheat
         ld a,0xfd
         in a,(0xfe)
         bit 3,a
         jr nz,nofuelcheat
         xor a
         ;ld (fuelcheat1),a
         ld b,a
         ld c,a
         ld (fuelcheat2),bc
nofuelcheat
         ld a,0xbf
         in a,(0xfe)
         bit 1,a
         jr nz,nolivescheat
         xor a
         ld (livescheat),a
nolivescheat
         ld a,0xfb
         in a,(0xfe)
         bit 2,a
         jr nz,noenemycheat
         ld a,0xc9
         ld (EnemyCollision),a
noenemycheat
nocheat
        ld a,0xef
        in a,(0xfe)
         ld bc,0xdffe
         in b,(c)
         bit 0,b ;'p'
         jr nz,$+4
         res 3,a
         bit 1,b ;'o'
         jr nz,$+4
         res 4,a
         ld bc,0xfbfe
         in b,(c)
         bit 0,b ;'q'
         jr nz,$+4
         res 1,a
         ld bc,0xfdfe
         in b,(c)
         bit 0,b ;'a'
         jr nz,$+4
         res 2,a
         pop bc
        rra
        and 0x0f
        ld hl,tstick
        add a,l
        ld l,a
        jr nc,$+3
        inc h
        ld a,(hl)
        ret
tstick
        db 0,0,0,0
        db 0,6,8,7
        db 0,4,2,3
        db 0,5,1,0
GTSTCK2
        xor a
        ret

L00D8
;GTTRIG
;Address  : #00D8
;Function : Returns current trigger status
;Input    : A  - trigger button to test
;           0 = spacebar
;           1 = port 1, button A
;           2 = port 2, button A
;           3 = port 1, button B
;           4 = port 2, button B
;Output   : A  - #00 trigger button not pressed
;                #FF trigger button pressed
;Registers: AF
        or a
        jr nz,GTTRIG2
         ld a,0x7f
         in a,(0xfe)
         cpl
         rra
         jr c,gttrigok
        ld a,0xef
        in a,(0xfe)
        cpl
        rra
gttrigok
        sbc a,a
        ret
GTTRIG2
        xor a
        ret

setpgsscr8000c000
        call getuser_scr_low
        SETPG32KLOW
        call getuser_scr_high
        SETPG32KHIGH
        ret

getuser_scr_low
getuser_scr_low_patch=$+1
getuser_scr_low_patchN=0xff&(user_scr0_low^user_scr1_low)
        ld a,(user_scr1_low) ;ok
        ret

getuser_scr_high
getuser_scr_high_patch=$+1
getuser_scr_high_patchN=0xff&(user_scr0_high^user_scr1_high)
        ld a,(user_scr1_high) ;ok
        ret

changescrpg
        ld hl,getuser_scr_low_patch
        ld a,(hl)
        xor getuser_scr_low_patchN
        ld (hl),a
        ld hl,getuser_scr_high_patch
        ld a,(hl)
        xor getuser_scr_high_patchN
        ld (hl),a
        ld a,(curscrnum_int)
        xor 1
        ld (curscrnum_int),a
        ret

        display $
        ds 0x2000-$

        include "HWC1.ASM"

;>=0x4000 for system INT
MUZHOOK;#FD9F ;$FD9F is one of the interrupt service routine hooks (HTIMI) and it's called every 50/60 times per second by the BIOS.
        ret
        ret
        ret

L0090
;GICINI
;Address  : #0090
;Function : Initialises PSG and sets initial value for the PLAY statement
;Registers: All
shutay
        push bc
        push de
        ld de,0xe00
shutay0
        dec d
        ld bc,0xfffd
        out (c),d
        ld b,0xbf
        out (c),e
        jr nz,shutay0
        pop de
        pop bc
        ret
       
L0093
;WRTPSG
;Address  : #0093
;Function : Writes data to PSG-register
;Input    : A  - PSG register number
;           E  - data write
        push bc
        ld bc,0xfffd
        out (c),a
        ld b,0xbf
        out (c),e
        pop bc
        ret
       
L0096
;RDPSG
;Address  : #0096
;Function : Reads value from PSG-register
;Input    : A  - PSG-register read
;Output   : A  - value read
        push bc
        ld bc,0xfffd
        out (c),a
        in a,(c)
        pop bc
        ret

end

        display "End=",end
        ;display "Free after end=",/d,#c000-end
        display "Size ",/d,end-begin," bytes"
        savebin "hws.com",begin,end-begin
        LABELSLIST "../../../us/user.l"