// 11.0592MHz=>921600 T0 clk=>112.5 ops=2.27`5s time // Code is big-endian! public BaudRate equ 2400 // Communication speed public StackSiz51 equ 24 // LaserGun stack size required MagicRAMw equ 0x53AC // RAM-check TestChar equ 't' // For Ph_Test MaxDecimal equ 99 // If dec>99 BauDiv equ 28800/BaudRate // 3=9600, 6=4800, 12=2400 (PCON=0) /* Init display: Pn-Player ID Gx-Game mode: A=Anarchy, G=Green team, R=Red team Display: Lt-Loading Fn-Shot from friend detected En-Shot from enemy detected but already dead Sn-Shot down by enemy dt-Currently dead Left dot-reloading Right dot-dead */ /******************************/ seg data org 0x00 DataStart: rb 4 // r0-r3 #define DispL r4 #define DispR r5 #define Timer r6 #define XMitPhase r7 // 0='s';1=PktType;2=SwConfigX;3=PktData;4=XSumH;5=XSumL;6='e' rb 4 TimPhase: rb 1 // Timer for current phase TimLED4: rb 1 // 4-LED period TimScroll: rb 1 // Scroll advance to next char ScrollPtr: rb 1 // Scroll-text start rel. ScrBase SeriCnt: rb 1 // Shots in current series CAPktEnd: rb 1 // End of ConfigReq being answered (or 0) WDogCnt: rb 1 // WatchDog timer count-down Phase: rb 1 // Current phase # (see below) Ph_CfgDump equ 0 // Configuration to display dump [Phase1=sub-phase] Ph_Ammo equ 1 // Normal Ammo display Ph_Laser equ 2 // Laser on Ph_Delay equ 3 // Laser off, laser button disabled Ph_First equ 4 // Additional first-in-series delay // Laser allowed boundary Ph_Reload equ 5 // Reload countdown period [Phase1=cdown] Ph_Dead equ 6 // Dead-state countdown period [Phase1=cdown] Ph_Test equ 7 // Test mode with transmit/receive of 'T' Phase1: rb 1 // Sub-phase // Ph_CfgDump: CD_Bootup equ 0 // Right after boot-up CD_PNum equ 1 // Player no. (P#) CD_GMode equ 2 // Game mode (G#: Anarchy, Green, Red) CD_LEDs equ 3 // BBS_QuietL [Ld] CD_Sound equ 4 // BBS_QuietS [Sd] CD_WDogs equ 5 // WDogsCnt (dr, TU) CD_WDogsN equ 6 // {TU} CD_RSwChg equ 7 // RSwChgs (SC, TU) CD_RSwChgN equ 8 // {TU} CD_TotSh equ 9 // TotShotsW (FS, [TH], TU) CD_TotShM equ 10 // {[TH]} CD_TotShN equ 11 // {TU} CD_Grave0 equ 12 // GraveW #0 (d#, [TH], TU) CD_GraveL equ 60 // GraveW #++F(d#, [TH], TU) CD_Last equ 60 // Ph_Reload: Reload cycles countdown // Ph_Dead: Dead cycles countdown CurPktE: rb 1 // +1 of last L2 packet byte received XMitNib: rb 1 // Transmit-remaining nibble (or 0) PktNibble: rb 1 // Recevied L2 packet hex nibble CurPktS: rb 1 // Addr of size of L2 packet being received UserPktS: rb 1 // Addr of size of 1st L2 packet in user queue TimedL: rb 1 // Left digit of TimedDisp TimedR: rb 1 // Right digit of TimedDisp ConvDecW1: // For use by ConvDecW RxChkXSumW: rw 1 // Computed xsum of incoming L2 packet XMitXSumW: rw 1 // XSum being computed during XMit XMitType: rb 1 // Actual XMit L3 Pkt type - One of PktN_* below ClearTop: public TotShotsW: rw 1 // Fire statistics public RSwChgs: rb 1 // Run-Time switch configuration change # public WDogsCnt: rb 1 // # of gurus-WatchDog restarts since power-on public SwConfigXA equ $-DataStart // Address of SwConfigX SwConfigX: rb 1 // Copy of SwitchP SysFlagsX: rb 1 // [XMittedN|XMitByte|XMit1stNib|XMitHaveP|TimedDisp|XMitting|PktGotNib|PktRcvng] PktRcvng bit SysFlagsX.0 // Currently receiving packet (after 's') PktGotNib bit SysFlagsX.1 // Already got one hex nibble in PktNibble XMitting bit SysFlagsX.2 // Background packet transmit in progress TimedDisp bit SysFlagsX.3 // Generated 2-digit display override XMitHaveP bit SysFlagsX.4 // XMitNib is prepared and filled XMit1stNib bit SysFlagsX.5 // Transmit 1st nibble from XMitNib XMitByte bit SysFlagsX.6 // Transmitting byte instead of two nibbles XMittedN bit SysFlagsX.7 // Sth was already xmitted this round public UsrFlagsX: rb 1 // [RFU:2|FastFireRD|FullFireT|DisRSwChg|DispDotTR|DispDotRD|UnConfig] UnConfig bit UsrFlagsX.0 // Ignore all further configuration attempts DispDotRD bit UsrFlagsX.1 // Display LDot & RDot when [R]eload/[D]ead DispDotTR bit UsrFlagsX.2 // Display LDot & RDot when [T]ransmit/[R]eceive DisRSwChg bit UsrFlagsX.3 // Disable run-time switch reconfiguration FullFireT bit UsrFlagsX.4 // Transmit full 10B packets for fires (safer) FastFireRD bit UsrFlagsX.5 // Receive disable for FastFires (see FullFireT) /******************************/ public Mark_Start equ 's' // L1 layer packet start public Mark_End equ 'e' // L1 layer packet end public XSum_Base equ 0xB3A7 // L2 packet xsumming base number public XSum_Mul equ 13 // L2 packet xsumming advance multiply public PktN_Fire equ 'S' // L3 packet ID for fire public PktN_CfgR equ 'R' // L3 packet ID for configuration request public PktN_CfgA equ 'A' // L3 packet ID for configuration answer DispP equ P0 BMD_U equ 0x01 BMD_UR equ 0x02 BMD_UL equ 0x04 BMD_M equ 0x08 BMD_BR equ 0x10 BND_DOT equ 5 BBD_DOT equ DispP.BND_DOT BMD_DOT equ 1< BNM_LED3 equ 6 BMM_LED3 equ 1< Dead cycle divisor public T_Start: rb 1 // Startup info cycle delay public T_Reload: rb 1 // Reload cycle delay public T_Laser: rb 1 // Laser firing public T_Delay: rb 1 // Inter-Laser delay public T_First: rb 1 // Additional series start delay period public T_LED4: rb 1 // 1 of RY-LED switch period public T_Scroll: rb 1 // Scroll of one letter public T_ScrollF: rb 1 // Scroll of 1st two letters public T_Dead: rb 1 // 4LED-Dead (and Dead) cycle delay public T_TimedD: rb 1 // TimedDisp delay (temporary, non-scrolling) public AddrSpace equ $-DataStart // +1 of remote configurable address space LoadPartS equ $-LoadPart MagicRAM: rw 1 // Contains MagicRAMw for RAM-check public RxBufSiz equ 0x80+DataStart-$-StackSiz51 // Receive buffer size RxBuf: rb RxBufSiz // Receive buffer StackBtm: // Start of stack /******************************/ seg code org 0x0 // Reset, SUsage=6 Reset: jb BPI_Fire,BadRAM mov a,#high MagicRAMw xrl a,MagicRAM jnz BadRAM sjmp ResCont org 0xB // T0, SUsage=4 T0Int: push psw push acc inc Timer dec WDogCnt mov a,WDogCnt jnz NWDogFail inc WDogsCnt // Failing! WarmBoot: mov r0,#ClearTop-1 // Mustn't reset RAM sjmp ContBoot NWDogFail: pop acc pop psw reti org 0x23 // Ser, SUsage=14 SerInt: ajmp SerICont SwRConfig: inc RSwChgs sjmp WarmBoot ResCont: mov a,#low MagicRAMw xrl a,MagicRAM+1 jz SwRConfig BadRAM: mov MagicRAM,#high MagicRAMw mov MagicRAM+1,#low MagicRAMw mov r0,#LoadPart mov dptr,#LoadContn mov r2,#LoadPartS FillMem: clr a movc a,@a+dptr mov @r0,a inc r0 inc dptr djnz r2,FillMem ColdBoot: mov r0,#LoadPart-1 ContBoot: clr a mov IE,a mov TCON,a mov sp,#StackBtm-1 ClearMem: mov @r0,a djnz r0,ClearMem mov SwConfigX,SwitchP mov SysFlagsX,a mov Timer,#1 mov CurPktS,#RxBuf mov UserPktS,#RxBuf mov DispP,a jb BPI_Fire,0f mov MiscP,#~(BMM_DispL|BMM_DispR) jnb BPI_Fire,$ mov a,SwitchP xch a,SwConfigX xrl a,SwConfigX jz 0f mov Phase,#Ph_Test setb DispDotTR 0: mov MiscP,#~BMM_DispR mov UsrFlagsX,#0x03 //DEBUG!!! clr a mov IP,#0x10 // Pri: Ser=1 mov TCON,a mov TL1,#-BauDiv mov TH1,#-BauDiv mov TL0,a mov TH0,a mov TMOD,#0x20 // T1=m2, T0=m0 mov PCON,a // SerSpd=normal mov SCON,#0x50 // 8N1, T1, clr mov TCON,#0x50 // T1+T0=run, clr mov IE,#0x92 // Int: Ser+T0 mov r0,#TimPhase acall StartTim acall InitLED4 MainLoop: mov WDogCnt,#0 // Reset WatchDog // Check run-time change of configuration jb DisRSwChg,1f mov a,SwConfigX xrl a,SwitchP jz 1f ajmp SwRConfig 1: // Display refresh mov DispP,#0xFF xrl MiscP,#BMM_DispL|BMM_DispR mov a,Phase jnb BPM_DispR,0f jnb DispDotTR,6f jb Xmitting,7f 6: jnb DispDotRD,1f xrl a,#Ph_Reload jnz 1f 7: clr BBD_DOT 1: mov a,ScrollPtr jnz 4f mov a,DispL jnb TimedDisp,2f mov a,TimedL sjmp 2f 0: jnb DispDotTR,8f jb PktRcvng,9f 8: jnb DispDotRD,3f xrl a,#Ph_Dead jnz 3f 9: clr BBD_DOT 3: mov a,ScrollPtr jz 5f inc a 4: mov dptr,#ScrBase movc a,@a+dptr sjmp 2f 5: mov a,DispR jnb TimedDisp,2f mov a,TimedR 2: anl DispP,a // 4-LED cycle jb BBS_QuietL,NoLED4Fr mov a,Phase xrl a,#Ph_Dead jz NoLED4Fr mov r0,#TimLED4 acall QueryTim jnc NoLED4Fr jnb BBS_IsTeam,1f mov a,#BMM_LED0|BMM_LED2 jnb BBS_TeamN,5f mov a,#BMM_LED1|BMM_LED3 5: xrl MiscP,a sjmp 2f 1: mov a,#~BMM_LEDM orl a,MiscP rl a jb acc.(BNM_LED3+1),4f mov a,#~BMM_LED0 4: orl MiscP,#BMM_LEDM anl MiscP,a 2: mov r0,#TimLED4 mov a,T_LED4 acall StartTim NoLED4Fr: // Fire series maintenance jnb BPI_Fire,0f mov SeriCnt,#0 0: /*** Here end mandatory MainLoop routines ***/ mov r0,#TimPhase acall QueryTim jnc NoPhases mov dptr,#PhaseTab mov r1,#Phase1 mov a,Phase acall JmpByTab NoPhases: // Fire check mov a,Phase jz 1f dec a jnz 2f 1: jb BPI_Status,0f clr a mov Phase,a mov Phase1,a mov r0,#TimPhase acall StartTim sjmp CantFire 2: cjne a,#Ph_First-Ph_Ammo,CantFire mov a,SeriCnt dec a jz CantFire 0: jb BPI_Fire,CantFire mov a,SeriCnt subb a,SeriC_Max jnc CantFire mov a,Ammo jz CantFire jb XMitting,CantFire // Fire one shot NOW! inc SeriCnt mov Phase,#Ph_Laser dec Ammo clr BPM_Laser mov c,BBS_QuietS mov BPM_Sound,c inc TotShotsW+1 mov a,TotShotsW+1 jnz 1f inc TotShotsW 1: mov a,#PktN_Fire acall StartXMiX mov ScrollPtr,#0 acall DispAmmo mov a,T_Laser mov r0,#TimPhase acall StartTim CantFire: // Scroll Update mov r0,#TimScroll acall QueryTim jnc 6f clr TimedDisp mov a,ScrollPtr jz 6f mov dptr,#ScrBase+2 movc a,@a+dptr jnz 0f mov ScrollPtr,a sjmp 6f 0: inc ScrollPtr mov a,ScrollPtr movc a,@a+dptr jnz 1f mov a,T_ScrollF sjmp 2f 1: mov a,T_Scroll 2: acall StartTim 6: // Packet received? mov a,UserPktS mov r0,a xrl a,CurPktS jnz 0f GotNoSerS: ajmp GotNoSer ShortPkt: mov a,r0 acall RxBufInc push 0 //r0 mov r0,a sjmp ProcSPkt 0: mov a,@r0 ; jb acc.7,ShortPkt jb XMitting,GotNoSerS inc a add a,r0 subb a,#RxBuf+RxBufSiz jnc 1f add a,#RxBufSiz 1: add a,#RxBuf push acc mov a,@r0 clr c subb a,#3 jc FailRPktN mov @r0,a push 0 //r0 inc a mov r2,a acall RxBufInc mov r1,#RxChkXSumW+1 mov @r1,#low XSum_Base dec r1 mov @r1,#high XSum_Base 0: mov a,@r0 acall AddXSum acall RxBufInc djnz r2,0b pop 2 //r2 mov a,@r0 xrl a,@r1 FailRPktN: jnz FailRPktS acall RxBufInc mov a,@r0 inc r1 xrl a,@r1 jnz FailRPktS // XSum is correct mov a,r2 mov r0,a mov a,@r0 mov r2,a acall RxBufInc mov a,@r0 mov r3,a acall RxBufInc cjne r3,#PktN_Fire,NoPFire cjne r2,#1,FailRPktS // Fire packet received, @R0=remote SwConfigX ProcSPkt: mov a,@r0 jnb BBS_IsTeam,ShotDown // We're anarchy jnb acc.BNS_IsTeam,ShotDown // From anarchy one xrl a,SwConfigX jnb acc.BNS_TeamN,FriendS // One of our team mov a,@r0 ShotDown: xrl a,SwConfigX anl a,#BMS_IdentM jz FriendS // Really shot by enemy mov TimedL,#Font_E mov a,Phase xrl a,#Ph_Dead jz PrintIDR mov a,@r0 anl a,#0x0F rl a add a,#GraveW+1 mov r1,a inc @r1 mov a,@r1 jnz 0f dec r1 inc @r1 0: mov TimedL,#Font_S mov Phase,#Ph_Dead mov Phase1,DeadN anl MiscP,#~BMM_LEDM push 0 //r0 acall NxtDead pop 0 //r0 sjmp PrintIDR FriendS: mov TimedL,#Font_F PrintIDR: mov a,@r0 anl a,#0x0F mov dptr,#FontHex movc a,@a+dptr mov TimedR,a setb TimedDisp mov ScrollPtr,#0 mov a,T_TimedD mov r0,#TimScroll acall StartTim FailRPktS: sjmp FailRPkt NoPFire: cjne r3,#PktN_CfgR,NoPCfgR jnb XMitting,0f dec sp sjmp GotNoSer 0: mov a,@r0 xrl a,SwConfigX anl a,#BMS_IdentM jnz FailRPkt acall RxBufInc2 CfgNBlock: mov a,r2 jz FailRPkt mov a,@r0 acall RxBufInc2 jz CRRepRes mov r3,a mov a,r2 jz FailRPkt mov a,@r0 acall RxBufInc2 mov r1,a CfgBlock: mov a,r2 jz FailRPkt mov a,@r0 acall RxBufInc2 push acc mov a,r1 clr c subb a,#AddrSpace pop acc jnc SkipWrite jb UnConfig,SkipWrite mov @r1,a SkipWrite: inc r1 djnz r3,CfgBlock sjmp CfgNBlock CRRepRes: pop acc clr c subb a,#RxBuf+2 jnc 0f add a,#RxBufSiz 0: add a,#RxBuf mov CAPktEnd,a mov a,r0 mov UserPktS,a mov a,#CfgRS-ScrBase acall DoScroll mov a,#PktN_CfgA acall StartXMiX sjmp GotNoSer NoPCfgR: cjne r3,#PktN_CfgA,FailRPkt mov a,#CfgAS-ScrBase ScrRPkt: acall DoScroll FailRPkt: pop UserPktS GotNoSer: ajmp MainLoop /******************************/ PhaseTab: db PhCfgDump-PhaseTab db PhAmmo -PhaseTab db PhLaser -PhaseTab db PhDelay -PhaseTab db PhFirst -PhaseTab db PhReload -PhaseTab db PhDead -PhaseTab db PhTest -PhaseTab PhCfgDump: mov a,T_TimedD acall StartTim SkpCDump: inc @r1 mov dptr,#CfgDTab mov a,@r1 clr c subb a,#CD_Grave0 jnc CDGrave mov a,@r1 JmpByTab: movc a,@a+dptr jmp @a+dptr PhLaser: orl MiscP,#BMM_Laser|BMM_Sound inc Phase mov a,T_Delay sjmp StartTimS PhDelay: inc Phase mov a,Ammo jz PD_Reload // Do Reload mov a,T_First sjmp StartTimS PhTest: jb XMitting,PT_WaitTI mov a,#TestChar acall StartXMiX PT_WaitTI: mov a,SwConfigX swap a rr a anl a,#0x78 sjmp StartTimS PD_Reload: inc Phase mov Phase1,ReloadN mov Ammo,Ammo_Max mov a,#ReloadS-ScrBase acall DoScroll PhReload: dec Phase1 mov a,Phase1 jz NormAmmo mov DispL,#Font_L mov a,Phase1 acall PutHexFnR mov a,T_Reload sjmp StartTimP PhDead: xrl MiscP,#BMM_LEDM dec Phase1 mov a,Phase1 jz RAmmonLED NxtDead: mov B,DeadDivN div aB xch a,B jnz 0f mov DispL,#Font_D mov a,B acall PutHexFnR 0: mov a,T_Dead StartTimP: mov r0,#TimPhase StartTimS: ajmp StartTim RAmmonLED: acall InitLED4 PhFirst: NormAmmo: mov Phase,#Ph_Ammo PhAmmo: // PhAmmo shouldn't happen <= no timer ajmp DispAmmo CDGrave: cjne a,#CD_Last-CD_Grave0,1f sjmp NormAmmo 1: mov B,#3 div aB mov r2,a rl a add a,#GraveW mov r0,a mov a,@r0 inc r0 orl a,@r0 jz SkpCDump2 mov a,B cjne a,#0,0f mov DispL,#Font_D mov a,r2 PutHexFnR: mov dptr,#FontHex ajmp PutFontR 0: dec r0 mov r3,a acall ConvDecW cjne r3,#1,DispHexS mov a,@r0 sjmp DispHexS CfgDTab equ $-1 db CDPNum -CfgDTab db CDGMode -CfgDTab db CDLEDs -CfgDTab db CDSound -CfgDTab db CDWDogs -CfgDTab db CDWDogsN -CfgDTab db CDRSwChg -CfgDTab db CDRSwChgN-CfgDTab db CDTotSh -CfgDTab db CDTotShM -CfgDTab db CDTotShN -CfgDTab CDPNum: mov DispL,#Font_P mov a,SwConfigX anl a,#0x0F sjmp PutHexFnR CDGMode: mov DispL,#Font_G mov a,#Font_A jnb BBS_IsTeam,DoGaMode mov a,#Font_R jnb BBS_TeamN,DoGaMode mov a,#Font_G DoGaMode: mov DispR,a ret CDLEDs: jnb BBS_QuietL,SkpCDumpS mov DispL,#Font_L mov DispR,#Font_D ret CDSound: jnb BBS_QuietS,SkpCDumpS mov DispL,#Font_S mov DispR,#Font_D ret CDWDogs: mov a,WDogsCnt jz SkpCDump1 mov DispL,#Font_D mov DispR,#Font_R ret SkpCDump2: inc @r1 SkpCDump1: inc @r1 SkpCDumpS: ajmp SkpCDump CDWDogsN: mov a,WDogsCnt sjmp DispDecS CDRSwChg: mov a,RSwChgs jz SkpCDump1 mov DispL,#Font_S mov DispR,#Font_C ret CDRSwChgN: mov a,RSwChgs DispDecS: ajmp DispDec CDTotSh: mov a,TotShotsW orl a,TotShotsW+1 jz SkpCDump2 mov DispL,#Font_F mov DispR,#Font_S ret CDTotShM: mov r0,#TotShotsW acall ConvDecW mov a,@r0 sjmp DispHexS CDTotShN: mov r0,#TotShotsW acall ConvDecW DispHexS: ajmp DispHex /******************************/ SerICont: push psw push acc push 0 //r0 push 2 //r2 RetryRI: jbc RI,GotRI RetryTI: jbc TI,GotTI pop 2 //r2 pop 0 //r0 pop acc pop psw reti /******************************/ GotRI: mov a,SBUF jnb acc.7,5f jb FastFireRD,ScratchRI jb acc.6,ScratchRI mov r0,CurPktS mov @r0,a acall RxBufInc mov a,r0 xrl a,UserPktS jz ScratchRI mov a,r0 mov CurPktS,a sjmp ScratchRI 5: cjne a,#Mark_Start,0f mov r0,CurPktS acall RxBufInc mov a,r0 xrl a,UserPktS jz ScratchRI mov CurPktE,r0 setb PktRcvng clr PktGotNib sjmp RetryRI 0: cjne a,#Mark_End,1f jnb PktRcvng,RetryRI jb PktGotNib,ScratchRI clr PktRcvng mov a,CurPktE mov r0,CurPktS clr c subb a,r0 jnc 3f add a,#RxBufSiz 3: dec a jz RetryRI mov @r0,a mov a,CurPktE mov CurPktS,a // Successfuly received packet sjmp RetryRI 1: jnb PktRcvng,RetryRI clr c subb a,#'0' jc ScratchRI subb a,#10 jc GotRITen subb a,#'A'-('9'+1) jc ScratchRI subb a,#6 jc GotRISix ScratchRI: clr PktRcvng RetryRIS: sjmp RetryRI /******************************/ GotTI: jnb XMitting,RetryTI clr XMittedN jnb XMitHaveP,PrepXMit mov a,XMitNib SendPrepd: jb XMittedN,RetryTIS jbc XMitByte,XMitByteC jnb XMit1stNib,Have2ndN swap a Have2ndN: anl a,#0x0F add a,#'0' mov r2,a clr c subb a,#'9'+1 mov a,r2 jc XMitByteC add a,#'A'-('9'+1) XMitByteC: mov SBUF,a setb XMittedN mov c,XMit1stNib clr XMit1stNib mov XMitHaveP,c jnc PrepXMit RetryTIS: ajmp RetryTI /******************************/ GotRISix: add a,#6 GotRITen: add a,#10 jb PktGotNib,2f swap a mov PktNibble,a sjmp DoneFNRI 2: orl a,PktNibble mov r2,a mov r0,CurPktE acall RxBufInc mov a,UserPktS xrl a,r0 jz ScratchRI mov a,r0 xch a,CurPktE mov r0,a mov a,r2 mov @r0,a DoneFNRI: cpl PktGotNib sjmp RetryRIS /******************************/ PrepXMit: mov a,XMitPhase mov dptr,#PhXMitTab movc a,@a+dptr jmp @a+dptr PhXMitTab: db XPStart -PhXMitTab db XPType -PhXMitTab db XPSwCfg -PhXMitTab db XPData -PhXMitTab db XPXSumH -PhXMitTab db XPXSumL -PhXMitTab db XPEnd -PhXMitTab db XPFinish-PhXMitTab InvalCR: mov CAPktEnd,a XPFinish: clr XMitting sjmp RetryTIS XPStart: mov a,XMitType xrl a,#TestChar jnz 1f mov a,#TestChar sjmp 2f 1: xrl a,#TestChar^PktN_Fire jnz 0f jb FullFireT,0f mov a,SwConfigX clr acc.6 setb acc.7 2: mov XMitPhase,#6 //XPFinish-1 sjmp ContXMitB 0: mov a,#Mark_Start ContXMitB: setb XMitByte inc XMitPhase clr XMit1stNib ContXMit: setb XMitHaveP mov XMitNib,a ajmp SendPrepd XPType: mov XMitXSumW ,#high XSum_Base mov XMitXSumW+1,#low XSum_Base mov a,XMitType XMitXHexP: inc XMitPhase XMitXHex: push 1 //r1 push 3 //r3 push B mov r1,#XMitXSumW push acc acall AddXSum pop acc pop B pop 3 //r3 pop 1 //r1 XMitHex: clr XMitByte setb XMit1stNib sjmp ContXMit XPSwCfg: mov a,SwConfigX sjmp XMitXHexP XPData: mov a,XMitType xrl a,#PktN_CfgA jnz XPDatDone mov r0,UserPktS NxtBlock: mov a,r0 xrl a,CAPktEnd jz DoneAns mov a,@r0 dec @r0 mov r2,a acall RxBufInc mov a,r0 xrl a,CAPktEnd jz InvalCR // Invalid CfgReq mov a,r2 jz DoneBlock mov a,@r0 inc @r0 mov r0,a mov a,@r0 sjmp XMitXHex DoneBlock: acall RxBufInc mov UserPktS,r0 mov a,r0 xrl a,CAPktEnd jnz NxtBlock DoneAns: mov CAPktEnd,a // Cancel CfgA pending alert acall RxBufInc acall RxBufInc mov UserPktS,r0 XPDatDone: inc XMitPhase XPXSumH: mov a,XMitXSumW XMitHexP: inc XMitPhase sjmp XMitHex XPXSumL: mov a,XMitXSumW+1 sjmp XMitHexP XPEnd: mov a,#Mark_End sjmp ContXMitB /******************************/ StartXMiX: mov XMitType,a clr a mov XMitPhase,a clr XMitHaveP setb XMitting setb TI // Start XMit now! ret /******************************/ // I: A=text offset, O: Filled DispL+DispR, D: A,R0,R2 DoScroll: mov ScrollPtr,a mov r0,#TimScroll mov a,T_ScrollF sjmp StartTim /******************************/ // O: Filled DispL+DispR, D: A,B,R2 DispAmmo: mov a,Ammo // I: A=decimal, O: Filled DispL+DispR, D: A,B,R2 DispDec: mov R2,a clr c subb a,#100 jnc 0f mov a,MaxDecimal 0: mov a,R2 mov B,#10 div aB swap a orl a,B // I: A=hexadecimal, O: Filled DispL+DispR, D: A,R2 DispHex: mov dptr,#FontHex mov R2,a swap a anl a,#0x0F movc a,@a+dptr mov DispL,a mov a,R2 anl a,#0x0F PutFontR: movc a,@a+dptr mov DispR,a Ret1: ret /******************************/ InitLED4: orl MiscP,#BMM_LEDM jb BBS_QuietL,Ret1 anl MiscP,#~BMM_LED0 jnb BBS_IsTeam,0f jnb BBS_TeamN,0f xrl MiscP,#BMM_LED0|BMM_LED1 0: mov r0,#TimLED4 mov a,T_LED4 /******************************/ // I: R0=addr of byte, A=min time, O: @R0!=0, D:A StartTim: add a,Timer jnz 0f inc a 0: mov @R0,a ret /******************************/ // I: R0=addr of byte, C=1->success, D:A QueryTim: mov a,@R0 clr c jz 0f subb a,Timer mov c,acc.7 jnc 0f clr a mov @R0,a 0: ret /******************************/ RxBufInc2: dec r2 // I: R0=RxAddr, O: R0=RxAddr+1 RxBufInc: inc r0 cjne r0,#RxBuf+RxBufSiz,0f mov r0,#RxBuf 0: ret /******************************/ // I: @R1/W=xsum, A=Byte, O: @R1/W=xsum+Byte, D:A,B,R3 AddXSum: push 2 //r2 push acc inc r1 inc @r1 mov a,@r1 dec r1 jnz 0f inc @r1 0: mov B,#XSum_Mul mul aB mov r2,a mov r3,B mov a,@r1 mov B,#XSum_Mul mul aB add a,r3 mov r3,a pop acc add a,r2 inc r1 mov @r1,a dec r1 mov a,r3 addc a,#0 mov @r1,a pop 2 //r2 ret // I: R0=SrcWord, O: R0=ConvDecW1, A=LOW [R0/W], D:R1,R2 ConvDecW: inc sp mov r1,sp inc sp mov a,@r0 mov @r1,a inc r0 inc r1 mov a,@r0 mov @r1,a mov dptr,#CDW_Tab mov r2,#4 mov r0,#ConvDecW1 3: xchd a,@r0 swap a mov @r0,a inc r0 clr a xchd a,@r0 swap a mov @r0,a 2: mov a,#1 movc a,@a+dptr mov B,a mov a,@r1 clr c subb a,B push acc dec r1 clr a movc a,@a+dptr mov B,a mov a,@r1 subb a,B jc 1f mov @r1,a pop acc inc r1 mov @r1,a inc @r0 sjmp 2b 1: dec sp inc dptr inc dptr inc r1 mov a,@r0 dec r0 djnz r2,3b dec sp dec sp ret /******************************/ ScrBase: // Every text offset must >0 !!! FontHex: db Font_0,Font_1,Font_2,Font_3,Font_4,Font_5,Font_6,Font_7 db Font_8,Font_9,Font_A,Font_B,Font_C,Font_D,Font_E,Font_F ReloadS: db Font_R,Font_E,Font_L,Font_O,Font_A,Font_D,0 CfgAS: db Font_C,Font_O,Font_N,Font_F,Font_I,Font_G db Font_A,Font_N,Font_S,0 CfgRS: db Font_C,Font_O,Font_N,Font_F,Font_I,Font_G db Font_U,Font_R,Font_E,Font_D,0 if ($-ScrBase>=0x100) ScrBase equ 0 /******************************/ CDW_Tab: dw 1000,100,10,1 LoadContn: db 12 // Reload countdown db 40 // Dead state countdown db 15 // Maximum # of shots per one series db 40 // Ammo # in one clip db 40 // Remaining ammo in the current clip db 4 // 4LED-Dead -> Dead cycle divisor db 100 // Startup info cycle delay db 48 // Reload cycle delay db 8 // Laser firing db 2 // Inter-Laser delay db 24 // Additional series start delay period db 32 // 1 of RY-LED switch period db 25 // Scroll of one letter db 50 // Scroll of 1st two letters db 24 // 4LED-Dead (and Dead) cycle delay db 110 // TimedDisp delay (temporary, non-scrolling) if ($-LoadContn!=LoadPartS) LoadPartS equ 0