Login

Subversion Repositories NedoOS

Rev

Rev 1186 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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_jp),HL
        LD (on_int_sp2),SP
        LD SP,INTSTACK
        push af
        push bc
        push de
        ex de,hl
;если стек в экране, то восстанавливаем нулём, иначе de
        ld a,(on_int_sp+1)
        sub 0x40
        cp 0x3f
        jr nc,$+5 ;not screen
        ld hl,0
on_int_sp=$+1
        ld (0),hl ;восстановили запоротый стек

        exx
        ex af,af' ;'
        push af
        push bc
        push de
        push hl
        push ix
        push iy

int_curborder=$+1
        ld e,0
        OS_SETBORDER

curscrnum_int=$+1
        ld e,0
        OS_SETSCREEN
       
        call oldimer ;ei ;а что если выйдем поздно (по yield)? надо в конце обработчика убрать ei, но и это не поможет, т.к. yield сейчас с включенными прерываниями!!!

        ld a,(curpg16k) ;ok
        push af
        ld a,(curpg32klow) ;ok
        push af
        ld a,(curpg32khigh) ;ok
        push af

        if KEMPSTON
        GET_KEY
        ld a,lx
        ld (kempstonbuttons),a
        endif

        if VIRTUALKEYS
        ;GET_KEY
        ;ld a,c ;кнопка без учёта языка
        ;or a
        ;jr z,$+5
        ;ld (curkey),a
       
        OS_GETKEYMATRIX
        rr c ;'a'
        rla ;A
        rr c ;'s'
        rla ;B
        ld c,lx
        rr c ;'Space'
        rla ;Select
        ld c,hx
        rr c ;'Enter'
        rla ;Start
        add a,a
        bit 3,h ;7
        jr z,$+3
        inc a ;Up
        add a,a
        bit 4,h ;6
        jr z,$+3
        inc a ;Down
        add a,a
        bit 4,e ;5
        jr z,$+3
        inc a ;Left
        add a,a
        bit 2,h ;8
        jr z,$+3
        inc a ;Right
        ;cpl
       ifdef CLIENT
        ld (joyTMPstate),a ;TODO в очередь, а в логике брать в том же порядке
       else
        ld (joy1state),a
       endif
       ;display "joy1state=",joy1state
;bit - button (ZX key)
;7 - A (A)
;6 - B (S)
;5 - Select (Space)
;4 - Start (Enter)
;3 - Up (7)
;2 - Down (6)
;1 - Left (5)
;0 - Right (8)
        endif
       
        call setpgsmain40008000
        ;LD     BC,PAGE3
        ;LD     A,#C3
        ;OUT    (C),A
        call setpgc3

        CALL    PLAYS
        LD      A,(SOUNDW)
        CP      0
        CALL    Z,PLAYS3
        LD      A,5
        LD      (SOUNDGO),A

        pop af
        SETPG32KHIGH
        pop af
        SETPG32KLOW
        pop af
        SETPG16K

        ;call logic

        ld hl,timer
        inc (hl)

        pop iy
        pop ix
        pop hl
        pop de
        pop bc
        pop af
        ex af,af' ;'
        exx
        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

timer
        db 0

       if VIRTUALKEYS
joyTMPstate
        db 0xff
joy1state
        db 0xff
joy2state
        db 0xff
       endif
       
PLAYS
        LD      A,(SOUNDW)
        CP      0
        RET     Z
        LD      A,(MAP)
        CP      15
        JR      Z,BOSSPLA
        CP      31
        JR      Z,BOSSPLA
        CALL    #C005
        LD      A,(SOUNDW)
        DEC     A
        LD      (SOUNDW),A
        RET
BOSSPLA
        CALL    #CBB8+5
        LD      A,(SOUNDW)
        DEC     A
        LD      (SOUNDW),A
        RET
PLAYS3
        CALL    AFXFRAME
        LD      A,(SOUND1)
        DEC     A
        CP      0
        JP      Z,PLAYS4
        LD      (SOUND1),A
        RET
PLAYS4
        LD      A,(NEWLEVEL)
        CP      1
        JR      Z,PLAYS4A
        LD      A,(SOUNDGO)
        CALL    AFXPLAY
        LD      A,8
        LD      (SOUND1),A
        RET
PLAYS4A
        LD      A,(SOUNDGO)
        CP      5
        RET     Z
        CALL    AFXPLAY
        LD      A,8
        LD      (SOUND1),A
        RET
SOUND1  DEFB    8
SOUNDW  DEFB    200

kempstonbuttons
        db 0

       ifdef CLIENT
       if CLIENT
sendjoyTMP
;отправить joyTMP
        ld de,joyTMPstate ;ptr
        ld hl,1 ;сколько слать
        ld a,(datasoc)
        OS_WIZNETWRITE
        ;bit 7,h
        ;JR Z,SEND_OK   ;ошибок нет
        ;CP ERR_EMSGSIZE
        ;JP NZ,ERR_EXIT ;обработка ошибки
        ;OS_YIELD               ;не обязательно. Если время не критично,
                                                ;то отдадим квант времени системе.
        ;JR WAIT_SEND   ;буфер отправки переполнен, ждём освобождения
;SEND_OK
        ret

readstream0_retry
        halt;YIELD
readstream0
;bc=size
        push de ;ptr
        push bc ;размер
        ld h,b
        ld l,c ;ld hl,inetbuf_sz ;сколько читать
        ld a,(datasoc)
        OS_WIZNETREAD
        bit 7,h
        pop bc
        pop de ;ptr
       jr nz,readstream0_retry
        ;jr z,readstream_ok
        ;cp ERR_EAGAIN
        ;jr z,readstream0 ;вдруг ответ не успел прийти
        ;jp readstream_err
        ;ld hl,0 ;size
;readstream_ok
;hl=сколько прочитали
        ld a,h
        or l
        jr z,readstream0_retry
        ret

twobytes
        dw 0

readfrominet_tojoy1joy2
;hl=адрес процедуры, которую вызвать, если приняли сообщение (и так для всех сообщений в очереди)
        ld (readfrominet_call),hl
;принять одно сообщение из TCP в очередь
;если там есть, то дешифровать истинные joy1(от сервера), joy2(наш с задержкой)
;надо принять гарантированно хотя бы одно!!!
        ld de,twobytes
        call readinetqueue ;чтобы принять гарантированно хотя бы одно сообщение
inetqueue_oldsize=$+1
       ld hl,0 ;до вынимания этого сообщения (2 байт)
inetqueue_oldaddr=$+1
       ld de,0
;hl=сколько есть байтов данных
;de=где
readstream_parse0
        ld a,(de)
       or a
       jr z,readstream_parse_sync
        ld (joy1state),a
        inc de
        ld a,(de)
        ld (joy2state),a
       ;ld (logicindex),a
        inc de
        push de
        push hl
readfrominet_call=$+1
        call 0
        pop hl
        pop de
        dec hl
        dec hl
        ld a,h
        or l
        jr nz,readstream_parse0
       ld (inetqueue_cursize),hl
       ld hl,inetbuf
       ld (inetqueue_curaddr),hl
        ret
readstream_parse_sync
;неожиданно пришёл sync, перестаём парсить
       ld (inetqueue_cursize),hl
       ld (inetqueue_curaddr),de
        ret

readinetqueue_retry
       push de
        ld de,inetbuf
       ld (inetqueue_curaddr),de
        ld bc,inetbuf_sz
        call readstream0
       ld (inetqueue_cursize),hl
       pop de
readinetqueue
;читаем 2 байта из очереди в de
;если в очереди ничего нет, то подчитываем из интернета
inetqueue_cursize=$+1
        ld hl,0
inetqueue_curaddr=$+1
        ld bc,inetbuf
        ld a,h
        or l
        jr z,readinetqueue_retry
       ld (inetqueue_oldsize),hl
       ld (inetqueue_oldaddr),bc
        ld a,(bc)
        ld (de),a
        inc bc
        inc de
        dec hl
        ld a,(bc)
        ld (de),a
        inc bc
        inc de
        dec hl
       ld (inetqueue_cursize),hl
       ld (inetqueue_curaddr),bc
        ret

readinetblock
;de=addr
;hl=size (even)
        push de
        push hl
        call readinetqueue
        pop hl
        pop de
        inc de
        inc de
        dec hl
        dec hl
        ld a,h
        or l
        jr nz,readinetblock
        ret

inet_waitsync
        ;ld hl,inet_waitsync_check
        ;call readfrominet_tojoy1joy2
        ld de,twobytes;joy1state
        call readinetqueue;readstream0
        ld a,(twobytes)
        or a
        jr nz,inet_waitsync
        ld de,rndseed1
        call readinetqueue;readstream0
        ld de,rndseed2
        call readinetqueue;readstream0
        ;ld de,MESTO
        ;call readinetqueue;readstream0
       xor a
       ld (MESTO),a
        ld de,UNITS
        ld hl,UNITS_blocksz
        call readinetblock
       if LOGGING
       ld hl,0
       ld (logicindex),hl
       ld a,0
       ld (wrlog),a
       endif
;inet_waitsync_check
        ret

       else ;SERVER

readfrominet_tojoy2
;принять сколько получится из TCP в очередь
;если там есть полный joy2, то дешифровать для текущего фрейма логики (иначе останется старое значение joy2)
;костыль: принимаем сколько есть, если >=1, то берём последний байт
        ld de,inetbuf
;readstream0
        push de ;ptr
        ;push hl ;размер
        ld hl,inetbuf_sz;1 ;сколько читать
        ld a,(datasoc)
        OS_WIZNETREAD
        bit 7,h
        ;pop hl
        pop de ;ptr
        jr z,readstream_ok
        ;cp ERR_EAGAIN
        ;jr z,readstream0 ;вдруг ответ не успел прийти
        ;jp readstream_err
        ld hl,0 ;size
readstream_ok
;hl=сколько прочитали
        ld a,h
        or l
        jr z,serv_gotnothing
        add hl,de
        dec hl
        ld a,(hl) ;last byte received
        ld (joy2state),a
serv_gotnothing
        ret

sendjoy1joy2
       ld a,(joyTMPstate)
       ld (joy1state),a ;атомарно
       ;ld a,(joy2state)
       ;push af
       ;ld a,(logicindex)
       ;ld (joy2state),a
;отправить joy1, joy2
        ld de,joy1state ;ptr
        call sendjoy1joy2_de
       ;pop af
       ;ld (joy2state),a
        ret

       
sendjoy1joy2_de
        ld hl,2 ;сколько слать
sendblock
        ld a,(datasoc)
        OS_WIZNETWRITE
        ;bit 7,h
        ;JR Z,SEND_OK   ;ошибок нет
        ;CP ERR_EMSGSIZE
        ;JP NZ,ERR_EXIT ;обработка ошибки
        ;OS_YIELD               ;не обязательно. Если время не критично,
                                                ;то отдадим квант времени системе.
        ;JR WAIT_SEND   ;буфер отправки переполнен, ждём освобождения
;SEND_OK
        ret

       if 0
sendblock
;de=addr
;hl=size (even)
        push de
        push hl
        call sendjoy1joy2_de
        pop hl
        pop de
        inc de
        inc de
        dec hl
        dec hl
        ld a,h
        or l
        jr nz,sendblock
        ret
       endif

inet_sendsync
        ld de,twozeros
        call sendjoy1joy2_de
        ld de,rndseed1
        call sendjoy1joy2_de
        ld de,rndseed2
        call sendjoy1joy2_de
        ;ld de,MESTO
        ;call sendjoy1joy2_de
       xor a
       ld (MESTO),a
        ld de,UNITS
        ld hl,UNITS_blocksz
        call sendblock
       if LOGGING
       ld hl,0
       ld (logicindex),hl
       ld a,0
       ld (wrlog),a
       endif
        ret
twozeros
        dw 0
       
       endif ;SERVER

       if LOGGING
wrlog
       ret ;/nop
logicindex=$+1
        ld hl,0
        ld (logportion+0),hl
        ld hl,(joy1state)
        ld (logportion+2),hl
        ld hl,(rndseed1)
        ld (logportion+4),hl
        ld hl,(rndseed2)
        ld (logportion+6),hl
loghandle=$+1
        ld b,0
        ld de,logportion
        ld hl,8
        OS_WRITEHANDLE
       
        ld hl,(logicindex)
        ld a,h
        cp 15
        ret c
       ld a,0xc9
       ld (wrlog),a
       ld a,(loghandle)
       ld b,a
       OS_CLOSEHANDLE
        ret
       endif

logportion
        ds 8 ;time,joy1joy2,rndseed1,rndseed2

       endif