// // Original Uthernet ethernet card based on Cirrus Logic cs8900a // include "inc/cmdsys.plh" // // Include dependency on S/W IP stack // import etherip predef setEtherDriver(MAC, getlen, readframe, setlen, writeframe)#0 end // // Uthernet register offsets // const TX_DATA = $00 const RX_DATA = $00 const TX_CMD = $04 const TX_LEN = $06 const INT_STATUS = $08 const PREG_INDEX = $0A const PREG_DATA = $0C const AUTO_INC = $8000 // // Uthernet register addresses // byte[] slot // Init time only byte rxdata_lo, rxdata_hi byte txcmd byte txlen byte isq byte pregidx byte pregdata // // Uthernet MAC address // byte[6] utherMAC = $00,$0A,$99,$1E,$02,$A0 // // Defines for ASM routines // asm equates !SOURCE "vmsrc/plvmzp.inc" end // // Uthernet I/O functions // asm _pokeiow(val) LDA ESTKL,X end asm _pokeiowl STA $C000 LDA ESTKH,X end asm _pokeiowh STA $C000 RTS end // // PEEK BYTE FROM I/O SPACE // _peekio() // asm _peekio DEX end asm _peekiol LDA $C000 STA ESTKL,X LDA #$00 STA ESTKH,X RTS end // // PEEK WORD FROM I/O SPACE // _peekiow() // asm _peekiow DEX end asm _peekiowl LDA $C000 STA ESTKL,X end asm _peekiowh LDA $C000 STA ESTKH,X RTS end // // WRITE FRAME DATA INTO I/O SPACE // pokefrm(BUF, LEN) // asm pokefrm(buf, len) LDY #$00 LDA ESTKL+1,X STA SRCL LDA ESTKH+1,X STA SRCH LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN LDA ESTKL,X ROR ADC #$00 STA ESTKL,X BEQ + !BYTE $A9 - CLC INC ESTKH,X + BCS - POKELP LDA (SRC),Y end asm _pokefrml STA $C000 INY LDA (SRC),Y end asm _pokefrmh STA $C000 INY BNE + INC SRCH + DEC ESTKL,X BNE POKELP DEC ESTKH,X BNE POKELP INX RTS end // // READ FRAME DATA FROM I/O SPACE // peekfrm(BUF, LEN) // asm peekfrm(buf, len) LDY #$00 LDA ESTKL+1,X STA DSTL LDA ESTKH+1,X STA DSTH LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN LDA ESTKL,X ROR ADC #$00 STA ESTKL,X BEQ + !BYTE $A9 - CLC INC ESTKH,X + BCS - end asm _peekfrml PEEKLP LDA $C000 STA (DST),Y INY end asm _peekfrmh + LDA $C000 STA (DST),Y INY BNE + INC DSTH + DEC ESTKL,X BNE PEEKLP DEC ESTKH,X BNE PEEKLP EXPSW INX RTS end def pokeiow(io, data) _pokeiowl.1 = io _pokeiowh.1 = io+1 return _pokeiow(data) end def peekio(io) _peekiol.1 = io return _peekio() end def peekiow(io) _peekiowl.1 = io _peekiowh.1 = io+1 return _peekiow() end def pokepreg(reg, data) pokeiow(pregidx, reg) return pokeiow(pregdata, data) end def peekpreg(reg) pokeiow(pregidx, reg) return peekiow(pregdata) end // // Set the length of the next packet to send and wait for data space availability // def pokefrmlen(len) pokeiow(txcmd, $C0) pokeiow(txlen, len) repeat; until peekpreg($0138) & $0100 return 0 end // // Return the length of awaiting packet, 0 otherwise // def peekfrmlen word len len = 0 if peekiow(isq) & $3F == $04 if peekio(rxdata_hi) & $01 peekio(rxdata_lo) len.1 = peekio(rxdata_hi) len.0 = peekio(rxdata_lo) else peekio(rxdata_lo) pokepreg($0102, $0140) // Skip pkt fin fin return len end // // Identify Uthernet card and initialize // for slot = $90 to $F0 step $10 if (peekiow(slot+TX_CMD) & $CC3F) == $09 pokeiow(slot+PREG_INDEX, 0) if peekiow(slot+PREG_DATA) == $630E pokepreg($0114, $40) // RESET rxdata_hi = slot + 1 txcmd = slot + TX_CMD txlen = slot + TX_LEN isq = slot + INT_STATUS pregidx = slot + PREG_INDEX pregdata = slot + PREG_DATA _pokefrml.1 = slot _pokefrmh.1 = slot+1 _peekfrml.1 = slot _peekfrmh.1 = slot+1 pokepreg($0158, utherMAC:0) // MAC addr pokepreg($015A, utherMAC:2) // MAC addr pokepreg($015C, utherMAC:4) // MAC addr pokepreg($0102, $0100) // Recv cfg pokepreg($0104, $0D00) // Recv ctrl pokepreg($0106, $8200) // Xmit cfg pokepreg($0112, $00C0) // Line ctrl // // Install etherip driver // puts("Found Uthernet I in slot #") putc('0' + ((slot - $80) >> 4)) putln setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm) return modkeep fin fin next // // Not found // return -1 done