diff --git a/src/inc/fileio.plh b/src/inc/fileio.plh index 05bc8e1..51da5b8 100644 --- a/src/inc/fileio.plh +++ b/src/inc/fileio.plh @@ -37,6 +37,7 @@ import fileio word getpfx word setpfx word getfileinfo + word geteof word open word close word read diff --git a/src/libsrc/dgr.pla b/src/libsrc/dgr.pla index 087bef4..079f009 100755 --- a/src/libsrc/dgr.pla +++ b/src/libsrc/dgr.pla @@ -1,5 +1,5 @@ include "inc/cmdsys.plh" -sysflags $000F // Reserve all text pages +sysflags restxt1|restxt2|resxtxt1|resxtxt2 // Reserve all text pages // // Apple II hardware constants. // @@ -40,615 +40,615 @@ byte[] oddclr = $00,$11,$22,$33,$44,$55,$66,$77 byte[] = $88,$99,$AA,$BB,$CC,$DD,$EE,$FF asm dgrInc(buff) -!SOURCE "vmsrc/plvmzp.inc" -GBASL = $26 -GBASH = $27 -GBASE = GBASL -GCLR = $30 +!SOURCE "vmsrc/plvmzp.inc" +GBASL = $26 +GBASH = $27 +GBASE = GBASL +GCLR = $30 end // // Plot pixel // export asm dgrPlot(buff, x, y)#0 - ; GET BUFFER ADDRESS - STX ESP - LDA ESTKL+2,X - STA SRCL - LDA ESTKH+2,X - STA SRCH - LDA ESTKL,X ; Y COORD - AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+1,X ; X COORD - LSR ESTKL,X - LDX GCLR ; COLOR - PHP - SEI + ; GET BUFFER ADDRESS + STX ESP + LDA ESTKL+2,X + STA SRCL + LDA ESTKH+2,X + STA SRCH + LDA ESTKL,X ; Y COORD + AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDA ESTKL+1,X ; X COORD + LSR ESTKL,X + LDX GCLR ; COLOR + PHP + SEI end asm _dgrPlotPix - JSR $3000 - PLP - LDX ESP - INX - INX + JSR $3000 + PLP + LDX ESP INX - RTS + INX + INX + RTS end // // Plot horizontal row of pixels // export asm dgrHLin(buff, x1, x2, y)#0 - ; GET BUFFER ADDRESS - STX ESP - LDA ESTKL+3,X - STA SRCL - LDA ESTKH+3,X - STA SRCH - LDA ESTKL,X ; Y COORD - AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+2,X ; X1 COORD - LSR ESTKL,X - PHP -- PLP - PHP - SEI - LDX GCLR ; COLOR + ; GET BUFFER ADDRESS + STX ESP + LDA ESTKL+3,X + STA SRCL + LDA ESTKH+3,X + STA SRCH + LDA ESTKL,X ; Y COORD + AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDA ESTKL+2,X ; X1 COORD + LSR ESTKL,X + PHP +- PLP + PHP + SEI + LDX GCLR ; COLOR end asm _dgrHLinPix - JSR $3000 - LDX ESP - INC ESTKL+2,X ; X1 COORD - LDA ESTKL+2,X - CMP ESTKL+1,X ; X2 COORD - BCC - - BEQ - - PLP - INX - INX - INX + JSR $3000 + LDX ESP + INC ESTKL+2,X ; X1 COORD + LDA ESTKL+2,X + CMP ESTKL+1,X ; X2 COORD + BCC - + BEQ - + PLP INX - RTS + INX + INX + INX + RTS end // // Plot horizontal row of pixels // export asm dgrVLin(buff, x, y1, y2)#0 - ; GET BUFFER ADDRESS - STX ESP - LDA ESTKL+3,X - STA SRCL - LDA ESTKH+3,X - STA SRCH - LDA ESTKL+1,X ; Y1 COORD -- AND #$FE - TAY - LDA (SRC),Y - STA GBASL - INY - LDA (SRC),Y - STA GBASH - LDA ESTKL+1,X - LSR - LDA ESTKL+2,X ; X COORD - LDX GCLR ; COLOR - PHP - SEI + ; GET BUFFER ADDRESS + STX ESP + LDA ESTKL+3,X + STA SRCL + LDA ESTKH+3,X + STA SRCH + LDA ESTKL+1,X ; Y1 COORD +- AND #$FE + TAY + LDA (SRC),Y + STA GBASL + INY + LDA (SRC),Y + STA GBASH + LDA ESTKL+1,X + LSR + LDA ESTKL+2,X ; X COORD + LDX GCLR ; COLOR + PHP + SEI end asm _dgrVLinPix - JSR $3000 - PLP - LDX ESP - INC ESTKL+1,X ; Y1 COORD - LDA ESTKL+1,X - CMP ESTKL,X ; Y2 COORD - BCC - - BEQ - - INX - INX + JSR $3000 + PLP + LDX ESP + INC ESTKL+1,X ; Y1 COORD + LDA ESTKL+1,X + CMP ESTKL,X ; Y2 COORD + BCC - + BEQ - INX - INX - RTS + INX + INX + INX + RTS end // // Draw sprite // export asm dgrBLT(buff, x, y, width, height, src)#0 - LDA ESTKL,X ; SPRITE - STA SRCL - LDA ESTKH,X - STA SRCH - LDA ESTKL+5,X - STA DSTL - LDA ESTKH+5,X - STA DSTH - LDA ESTKL+4,X ; X1 COORD - CMP #80 - BPL ++++ - CLC - ADC ESTKL+2,X - BMI ++++ - STA ESTKH+2,X ; X2 COORD - LDA ESTKL+3,X ; Y1 COORD - CMP #48 - BPL ++++ - STA ESTKH+3,X ; Y COORD - CLC - ADC ESTKL+1,X - BMI ++++ - STA ESTKH+1,X ; Y2 COORD - STX ESP - LDA ESTKH+3,X -- CMP #48 - BCC + - LDA SRCL ; SKIP TO NEXT ROW - CLC - ADC ESTKL+2,X ; WIDTH - STA SRCL - LDA SRCH - ADC #$00 - STA SRCH - BNE +++ -+ AND #$FE - TAY - LDA (DST),Y - STA GBASL - INY - LDA (DST),Y - STA GBASH - LDA ESTKL+4,X ; X1 COORD - STA ESTKH+4,X ; X COORD - PHP - SEI --- CMP #80 - BCS ++ - STA TMP - LDA ESTKH+3,X ; Y COORD - LSR - LDY #$00 - LDA (SRC),Y - BMI ++ - TAX - LDA TMP + LDA ESTKL,X ; SPRITE + STA SRCL + LDA ESTKH,X + STA SRCH + LDA ESTKL+5,X + STA DSTL + LDA ESTKH+5,X + STA DSTH + LDA ESTKL+4,X ; X1 COORD + CMP #80 + BPL ++++ + CLC + ADC ESTKL+2,X + BMI ++++ + STA ESTKH+2,X ; X2 COORD + LDA ESTKL+3,X ; Y1 COORD + CMP #48 + BPL ++++ + STA ESTKH+3,X ; Y COORD + CLC + ADC ESTKL+1,X + BMI ++++ + STA ESTKH+1,X ; Y2 COORD + STX ESP + LDA ESTKH+3,X +- CMP #48 + BCC + + LDA SRCL ; SKIP TO NEXT ROW + CLC + ADC ESTKL+2,X ; WIDTH + STA SRCL + LDA SRCH + ADC #$00 + STA SRCH + BNE +++ ++ AND #$FE + TAY + LDA (DST),Y + STA GBASL + INY + LDA (DST),Y + STA GBASH + LDA ESTKL+4,X ; X1 COORD + STA ESTKH+4,X ; X COORD + PHP + SEI +-- CMP #80 + BCS ++ + STA TMP + LDA ESTKH+3,X ; Y COORD + LSR + LDY #$00 + LDA (SRC),Y + BMI ++ + TAX + LDA TMP end asm _dgrBLTPix - JSR $4000 - LDX ESP -++ INC SRCL - BNE + - INC SRCH -+ INC ESTKH+4,X ; X COORD - LDA ESTKH+4,X - BMI -- - CMP ESTKH+2,X ; X2 COORD - BCC -- - PLP -+++ INC ESTKH+3,X ; Y COORD - LDA ESTKH+3,X - BMI - - CMP ESTKH+1,X ; Y2 COORD - BCC - -++++ INX - INX - INX - INX - INX + JSR $4000 + LDX ESP +++ INC SRCL + BNE + + INC SRCH ++ INC ESTKH+4,X ; X COORD + LDA ESTKH+4,X + BMI -- + CMP ESTKH+2,X ; X2 COORD + BCC -- + PLP ++++ INC ESTKH+3,X ; Y COORD + LDA ESTKH+3,X + BMI - + CMP ESTKH+1,X ; Y2 COORD + BCC - +++++ INX INX - RTS + INX + INX + INX + INX + RTS end // // Internal set pixel routine // asm _dgrSetPix - BCS ++ - ; EVEN ROW - LSR - TAY - BCS + + BCS ++ + ; EVEN ROW + LSR + TAY + BCS + end asm _dgrSetEvnEvn - ; EVEN PIXEL - LDA $2000,X - AND #$0F - STA TMP - JSR $0100 ; LDA AUX (DST),Y - AND #$F0 - ORA TMP - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM - RTS + ; EVEN PIXEL + LDA $2000,X + AND #$0F + STA TMP + JSR $0100 ; LDA AUX (DST),Y + AND #$F0 + ORA TMP + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM + RTS end asm _dgrSetEvnOdd - ; ODD PIXEL -+ LDA $1000,X - AND #$0F - STA TMP - LDA (GBASE),Y - AND #$F0 - ORA TMP - STA (GBASE),Y - RTS - ; ODD ROW -++ LSR - TAY - BCS +++ + ; ODD PIXEL ++ LDA $1000,X + AND #$0F + STA TMP + LDA (GBASE),Y + AND #$F0 + ORA TMP + STA (GBASE),Y + RTS + ; ODD ROW +++ LSR + TAY + BCS +++ end asm _dgrSetOddEvn - ; EVEN PIXEL - LDA $2000,X - AND #$F0 - STA TMP - JSR $0100 ; LDA AUX (DST),Y - AND #$0F - ORA TMP - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM - RTS + ; EVEN PIXEL + LDA $2000,X + AND #$F0 + STA TMP + JSR $0100 ; LDA AUX (DST),Y + AND #$0F + ORA TMP + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM + RTS end asm _dgrSetOddOdd - ; ODD PIXEL -+++ LDA $1000,X - AND #$F0 - STA TMP - LDA (GBASE),Y - AND #$0F - ORA TMP - STA (GBASE),Y - RTS + ; ODD PIXEL ++++ LDA $1000,X + AND #$F0 + STA TMP + LDA (GBASE),Y + AND #$0F + ORA TMP + STA (GBASE),Y + RTS end asm auxRead - STA $C003 ; READ AUX MEM - LDA (GBASE),Y - STA $C002 ; READ MAIN MEM - RTS + STA $C003 ; READ AUX MEM + LDA (GBASE),Y + STA $C002 ; READ MAIN MEM + RTS end // // Draw 8x8 tile (forced to 2x2 block address) // export asm dgrTile(buff, x, y, src)#0 - STX ESP - LDA ESTKL,X ; TILE - STA SRCL - LDA ESTKH,X - STA SRCH - LDA ESTKL+3,X - STA DSTL - LDA ESTKH+3,X - STA DSTH - LDA ESTKL+2,X ; X1 COORD - CMP #80 - BPL ++++ - CLC - ADC #$08 - BMI ++++ - STA ESTKH+2,X ; X2 COORD - LDA ESTKL+1,X ; Y1 COORD - CMP #48 - BPL ++++ - STA TMPL ; Y COORD - CLC - ADC #$08 - BMI ++++ - STA ESTKH+1,X ; Y2 COORD - LDA TMPL ; Y COORD -- CMP #48 - BCC + - LDA SRCL ; SKIP TO NEXT ROW - ADC #$07 ; CARRY = 1 - STA SRCL - LDA SRCH - ADC #$00 - STA SRCH - BNE +++ -+ AND #$FE - TAY - LDA (DST),Y - STA GBASL - INY - LDA (DST),Y - STA GBASH - LDA ESTKL+2,X ; X1 COORD - STA TMPH ; X COORD - PHP - SEI --- LSR - TAY - CMP #40 - LDX #$00 - LDA (SRC,X) - INC SRCL - BNE + - INC SRCH -+ BCS + - STA $C005 ; WRITE AUX MEM - STA (GBASE),Y - STA $C004 ; WRITE MAIN MEM -+ LDA (SRC,X) - INC SRCL - BNE + - INC SRCH -+ BCS ++ - STA (GBASE),Y -++ INC TMPH ; X COORD - INC TMPH ; X COORD - LDX ESP - LDA TMPH - BMI -- - CMP ESTKH+2,X ; X2 COORD - BCC -- - PLP -+++ INC TMPL ; Y COORD - INC TMPL ; Y COORD - LDA TMPL - BMI - - CMP ESTKH+1,X ; Y2 COORD - BCC - -++++ INX - INX - INX + STX ESP + LDA ESTKL,X ; TILE + STA SRCL + LDA ESTKH,X + STA SRCH + LDA ESTKL+3,X + STA DSTL + LDA ESTKH+3,X + STA DSTH + LDA ESTKL+2,X ; X1 COORD + CMP #80 + BPL ++++ + CLC + ADC #$08 + BMI ++++ + STA ESTKH+2,X ; X2 COORD + LDA ESTKL+1,X ; Y1 COORD + CMP #48 + BPL ++++ + STA TMPL ; Y COORD + CLC + ADC #$08 + BMI ++++ + STA ESTKH+1,X ; Y2 COORD + LDA TMPL ; Y COORD +- CMP #48 + BCC + + LDA SRCL ; SKIP TO NEXT ROW + ADC #$07 ; CARRY = 1 + STA SRCL + LDA SRCH + ADC #$00 + STA SRCH + BNE +++ ++ AND #$FE + TAY + LDA (DST),Y + STA GBASL + INY + LDA (DST),Y + STA GBASH + LDA ESTKL+2,X ; X1 COORD + STA TMPH ; X COORD + PHP + SEI +-- LSR + TAY + CMP #40 + LDX #$00 + LDA (SRC,X) + INC SRCL + BNE + + INC SRCH ++ BCS + + STA $C005 ; WRITE AUX MEM + STA (GBASE),Y + STA $C004 ; WRITE MAIN MEM ++ LDA (SRC,X) + INC SRCL + BNE + + INC SRCH ++ BCS ++ + STA (GBASE),Y +++ INC TMPH ; X COORD + INC TMPH ; X COORD + LDX ESP + LDA TMPH + BMI -- + CMP ESTKH+2,X ; X2 COORD + BCC -- + PLP ++++ INC TMPL ; Y COORD + INC TMPL ; Y COORD + LDA TMPL + BMI - + CMP ESTKH+1,X ; Y2 COORD + BCC - +++++ INX INX - RTS + INX + INX + RTS end // // Draw a string of tiles // export asm dgrTileStr(buff, x, y, tilestr, strlen, tilebuff)#0 -- DEX - DEX - DEX - DEX - LDA ESTKL+9,X ; BUFF - STA ESTKL+3,X - LDA ESTKH+9,X - STA ESTKH+3,X - LDA ESTKL+8,X ; X COORD - STA ESTKL+2,X - LDA ESTKL+7,X ; Y COORD - STA ESTKL+1,X - LDA ESTKL+4,X ; TILE - STA ESTKL,X - LDA ESTKH+4,X ; TILE - STA ESTKH,X +- DEX + DEX + DEX + DEX + LDA ESTKL+9,X ; BUFF + STA ESTKL+3,X + LDA ESTKH+9,X + STA ESTKH+3,X + LDA ESTKL+8,X ; X COORD + STA ESTKL+2,X + LDA ESTKL+7,X ; Y COORD + STA ESTKL+1,X + LDA ESTKL+4,X ; TILE + STA ESTKL,X + LDA ESTKH+4,X ; TILE + STA ESTKH,X end asm _dgrTileTile - JSR $5000 - LDA ESTKL+4,X ; UPDATE X COORD - CLC - ADC #$08 - CMP #80 ; OFF RIGHT SIDE - BPL + - STA ESTKL+4,X - DEC ESTKL+1,X ; DEC STRLEN - BNE - -+ TXA - CLC - ADC #6 - TAX - RTS + JSR $5000 + LDA ESTKL+4,X ; UPDATE X COORD + CLC + ADC #$08 + CMP #80 ; OFF RIGHT SIDE + BPL + + STA ESTKL+4,X + DEC ESTKL+1,X ; DEC STRLEN + BNE - ++ TXA + CLC + ADC #6 + TAX + RTS end // // Draw a string of tiles // export asm dgrFill(buff, x, y, tile)#0 - LDA ESTKL+2,X - AND #$0F - STA ESTKL+2,X - LDA ESTKL+1,X - AND #$0F - STA ESTKL+1,X - LDA #$00 - SEC - SBC ESTKL+2,X ; ORIGINAL X - STA ESTKL+2,X - STA ESTKH+2,X - LDA #$00 - SEC - SBC ESTKL+1,X - STA ESTKL+1,X -- DEX - DEX - DEX - DEX - LDA ESTKL+7,X ; BUFF - STA ESTKL+3,X - LDA ESTKH+7,X - STA ESTKH+3,X - LDA ESTKL+6,X ; X COORD - STA ESTKL+2,X - LDA ESTKL+5,X ; Y COORD - STA ESTKL+1,X - LDA ESTKL+4,X ; TILE - STA ESTKL,X - LDA ESTKH+4,X ; TILE - STA ESTKH,X + LDA ESTKL+2,X + AND #$0F + STA ESTKL+2,X + LDA ESTKL+1,X + AND #$0F + STA ESTKL+1,X + LDA #$00 + SEC + SBC ESTKL+2,X ; ORIGINAL X + STA ESTKL+2,X + STA ESTKH+2,X + LDA #$00 + SEC + SBC ESTKL+1,X + STA ESTKL+1,X +- DEX + DEX + DEX + DEX + LDA ESTKL+7,X ; BUFF + STA ESTKL+3,X + LDA ESTKH+7,X + STA ESTKH+3,X + LDA ESTKL+6,X ; X COORD + STA ESTKL+2,X + LDA ESTKL+5,X ; Y COORD + STA ESTKL+1,X + LDA ESTKL+4,X ; TILE + STA ESTKL,X + LDA ESTKH+4,X ; TILE + STA ESTKH,X end asm _dgrFillTile - JSR $5000 - LDA ESTKL+2,X ; UPDATE X COORD - CLC - ADC #$08 - STA ESTKL+2,X - CMP #80 ; OFF RIGHT SIDE? - BMI - - LDA ESTKH+2,X ; RESTORE X COORD - STA ESTKL+2,X - LDA ESTKL+1,X ; UPDATE Y COORD - CLC - ADC #$08 - STA ESTKL+1,X - CMP #48 ; OFF BOTTOM? - BMI - - INX - INX - INX - INX - RTS + JSR $5000 + LDA ESTKL+2,X ; UPDATE X COORD + CLC + ADC #$08 + STA ESTKL+2,X + CMP #80 ; OFF RIGHT SIDE? + BMI - + LDA ESTKH+2,X ; RESTORE X COORD + STA ESTKL+2,X + LDA ESTKL+1,X ; UPDATE Y COORD + CLC + ADC #$08 + STA ESTKL+1,X + CMP #48 ; OFF BOTTOM? + BMI - + INX + INX + INX + INX + RTS end // // Wait for VLB // asm vlbWait#0 -- LDA $C019 - BMI - -- LDA $C019 - BPL - - RTS +- LDA $C019 + BMI - +- LDA $C019 + BPL - + RTS end // // Set double lores graphics, return draw buffer // export def dgrMode#1 - ^showlores - ^showfull - ^showgraphics - ^showpage1 - ^ena80 = 0 - ^show80 = 0 -// ^mapaux = 0 - ^an3on + ^showlores + ^showfull + ^showgraphics + ^showpage1 + ^ena80 = 0 + ^show80 = 0 +// ^mapaux = 0 + ^an3on return 1 end // // Set text mode // export def txtMode#0 - ^showtext - ^showpage1 - ^ena80 = 0 - ^show40 = 0 - ^mapmain = 0 - ^an3on - call($FC58, 0, 0, 0, 0) // home() + ^showtext + ^showpage1 + ^ena80 = 0 + ^show40 = 0 + ^mapmain = 0 + ^an3on + call($FC58, 0, 0, 0, 0) // home() end // // Set display page, return other page // export def dgrShow(page)#1 - page = page & 1 - ^(showpage1 + page) - return page ^ 1 + page = page & 1 + ^(showpage1 + page) + return page ^ 1 end // -// Set color for cear & plot routines +// Set color for clear & plot routines // export def dgrColor(clr)#0 - ^$30 = clr & $0F + ^$30 = clr & $0F end // // Draw line // export def dgrLine(buff, x1, y1, x2, y2)#0 - byte dx, dy, dx2, dy2, pp - word sx, sy, err, dd2 + byte dx, dy, dx2, dy2, pp + word sx, sy, err, dd2 - if x1 < x2 - sx = 1 - dx = x2 - x1 - else - sx = -1 - dx = x1 - x2 - fin - if y1 < y2 - sy = 1 - dy = y2 - y1 - else - sy = -1 - dy = y1 - y2 - fin - dx2 = dx << 1 - dy2 = dy << 1 - if dx >= dy - // Horizontal line - if sx < 0 - pp = x1 - x1 = x2 - x2 = pp - pp = y1 - y1 = y2 - y2 = pp - sy = -sy - fin - dd2 = dx2 - dy2 - err = dx - dy2 - sx = 1 - while dy - if err < 0 - dgrHLin(buff, x1, x1 + sx - 1, y1) - x1 = x1 + sx - y1 = y1 + sy - sx = 1 - dy-- - err = err + dd2 - else - sx++ - err = err - dy2 - fin - loop - if y2 == y1 - dgrHLin(buff, x1, x2, y1) - fin - else - // Vertical line - if sy < 0 - pp = x1 - x1 = x2 - x2 = pp - pp = y1 - y1 = y2 - y2 = pp - sx = -sx - fin - dd2 = dy2 - dx2 - err = dy - dx2 - sy = 1 - while dx - if err < 0 - dgrVLin(buff, x1, y1, y1 + sy - 1) - x1 = x1 + sx - y1 = y1 + sy - sy = 1 - dx-- - err = err + dd2 - else - sy++ - err = err - dx2 - fin - loop - if x2 == x1 - dgrVLin(buff, x1, y1, y2) - fin - fin + if x1 < x2 + sx = 1 + dx = x2 - x1 + else + sx = -1 + dx = x1 - x2 + fin + if y1 < y2 + sy = 1 + dy = y2 - y1 + else + sy = -1 + dy = y1 - y2 + fin + dx2 = dx << 1 + dy2 = dy << 1 + if dx >= dy + // Horizontal line + if sx < 0 + pp = x1 + x1 = x2 + x2 = pp + pp = y1 + y1 = y2 + y2 = pp + sy = -sy + fin + dd2 = dx2 - dy2 + err = dx - dy2 + sx = 1 + while dy + if err < 0 + dgrHLin(buff, x1, x1 + sx - 1, y1) + x1 = x1 + sx + y1 = y1 + sy + sx = 1 + dy-- + err = err + dd2 + else + sx++ + err = err - dy2 + fin + loop + if y2 == y1 + dgrHLin(buff, x1, x2, y1) + fin + else + // Vertical line + if sy < 0 + pp = x1 + x1 = x2 + x2 = pp + pp = y1 + y1 = y2 + y2 = pp + sx = -sx + fin + dd2 = dy2 - dx2 + err = dy - dx2 + sy = 1 + while dx + if err < 0 + dgrVLin(buff, x1, y1, y1 + sy - 1) + x1 = x1 + sx + y1 = y1 + sy + sy = 1 + dx-- + err = err + dd2 + else + sy++ + err = err - dx2 + fin + loop + if x2 == x1 + dgrVLin(buff, x1, y1, y2) + fin + fin end // // Clear the buffer // export def dgrClear(buff, clr)#0 - byte[32] clrtile + byte[32] clrtile - clr = evnclr[clr&$0F] | (oddclr[clr&$0F] << 8) - memset(@clrtile, clr, 32) - dgrFill(buff, 0, 0, @clrtile) + clr = evnclr[clr&$0F] | (oddclr[clr&$0F] << 8) + memset(@clrtile, clr, 32) + dgrFill(buff, 0, 0, @clrtile) end // // Make sure we are a 128K //e or //c // if MACHID & $F0 <> $B0 - puts("\n128K REQUIRED FOR DOUBLE LO-RES.") - ^$C010 - while ^$C000 < 128; loop - return -1 + puts("\n128K REQUIRED FOR DOUBLE LO-RES.") + ^$C010 + while ^$C000 < 128; loop + return -1 fin // // Assembly fixups diff --git a/src/libsrc/dhcp.pla b/src/libsrc/dhcp.pla index 6037e41..c8ec99c 100644 --- a/src/libsrc/dhcp.pla +++ b/src/libsrc/dhcp.pla @@ -2,29 +2,7 @@ // DHCP // include "inc/cmdsys.plh" -// -// Net object -// -import inet - word iNet -end -struc t_inet - word initIP - word serviceIP - word openUDP - word sendUDP - word closeUDP - word listenTCP - word connectTCP - word sendTCP - word closeTCP - word setInterfaceIP - word getInterfaceHA - word setDNS - word resolveIP - word setCallback - word setParam -end +include "inc/inet.plh" // // Needed to init subnet // @@ -109,58 +87,58 @@ byte[] endDHCP // // DEBUG // -byte boundstr = "Apple II bound to:\n" -byte dnsstr = "DNS: " -def putb(hexb) - return call($FDDA, hexb, 0, 0, 0) -end -def puth(hex) - return call($F941, hex >> 8, hex, 0, 0) -end -def putip(ipptr) - byte i - - for i = 0 to 2 - puti(ipptr->[i]); putc('.') - next - return puti(ipptr->[i]) -end -def dumpbytes(buf, len) - word i - - for i = 0 to len - 1 - putb(buf->[i]) - if i & 15 == 15 - putln - else - putc(' ') - fin - next -end -def dumpdhcp(pkt) - putb(pkt->dhcp_op);putln - putb(pkt->dhcp_htype);putln - putb(pkt->dhcp_hlen);putln - putb(pkt->dhcp_hops);putln - dumpbytes(@pkt->dhcp_xid, 4);putln - putip(@pkt->dhcp_clientip);putln - putip(@pkt->dhcp_yourip);putln - putip(@pkt->dhcp_serverip);putln - putip(@pkt->dhcp_gatewayip);putln - dumpbytes(@pkt->dhcp_opts, 48);putln -end +//byte boundstr = "Apple II bound to:\n" +//byte dnsstr = "DNS: " +//def putb(hexb) +// return call($FDDA, hexb, 0, 0, 0) +//end +//def puth(hex) +// return call($F941, hex >> 8, hex, 0, 0) +//end +//def putip(ipptr) +// byte i +// +// for i = 0 to 2 +// puti(ipptr->[i]); putc('.') +// next +// return puti(ipptr->[i]) +//end +//def dumpbytes(buf, len) +// word i +// +// for i = 0 to len - 1 +// putb(buf->[i]) +// if i & 15 == 15 +// putln +// else +// putc(' ') +// fin +// next +//end +//def dumpdhcp(pkt) +// putb(pkt->dhcp_op);putln +// putb(pkt->dhcp_htype);putln +// putb(pkt->dhcp_hlen);putln +// putb(pkt->dhcp_hops);putln +// dumpbytes(@pkt->dhcp_xid, 4);putln +// putip(@pkt->dhcp_clientip);putln +// putip(@pkt->dhcp_yourip);putln +// putip(@pkt->dhcp_serverip);putln +// putip(@pkt->dhcp_gatewayip);putln +// dumpbytes(@pkt->dhcp_opts, 48);putln +//end def parseopts(opts, match) byte i i = 0 while opts->[i] <> $FF and i < 64 - while !opts->[i] and i < 64 - i = i + 1 - loop + while !opts->[i] and i < 64 + i = i + 1 + loop if opts->[i] == match - return i - fin - i = i + opts->[i + 1] + 2 + return i + fin + i = i + opts->[i + 1] + 2 loop return -1 end @@ -171,41 +149,41 @@ def recvDHCP(remip, remport, pkt, len, param) //dumpdhcp(pkt) if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 == $0403 when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2] - is DHCP_OFFER - // - // Copy offer parameters to request - // - optsOP.2 = DHCP_REQUEST - memcpy(@optsIP.2, @pkt->dhcp_yourip, IP4ADR_SIZE) - servopts = parseopts(@pkt->dhcp_opts, 54) + 2 - if servopts >= 0 - optsSRV = 54 - memcpy(@optsSRV.2, @pkt->dhcp_opts.[servopts], IP4ADR_SIZE) - fin - iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP) - break - is DHCP_ACK - optsOP.2 = DHCP_ACK - // - // Copy parameters to working copy - // - memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE) - maskopts = parseopts(@pkt->dhcp_opts, 1) + 2 - if maskopts >= 0 - memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE) - fin - gwopts = parseopts(@pkt->dhcp_opts, 3) + 2 - if gwopts >= 0 - memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE) - fin - dnsopts = parseopts(@pkt->dhcp_opts, 6) + 2 - if dnsopts >= 0 - memcpy(@localdns, @pkt->dhcp_opts.[dnsopts], IP4ADR_SIZE) - fin - break - otherwise - dumpdhcp(pkt) - wend + is DHCP_OFFER + // + // Copy offer parameters to request + // + optsOP.2 = DHCP_REQUEST + memcpy(@optsIP.2, @pkt->dhcp_yourip, IP4ADR_SIZE) + servopts = parseopts(@pkt->dhcp_opts, 54) + 2 + if servopts >= 0 + optsSRV = 54 + memcpy(@optsSRV.2, @pkt->dhcp_opts.[servopts], IP4ADR_SIZE) + fin + iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP) + break + is DHCP_ACK + optsOP.2 = DHCP_ACK + // + // Copy parameters to working copy + // + memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE) + maskopts = parseopts(@pkt->dhcp_opts, 1) + 2 + if maskopts >= 0 + memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE) + fin + gwopts = parseopts(@pkt->dhcp_opts, 3) + 2 + if gwopts >= 0 + memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE) + fin + dnsopts = parseopts(@pkt->dhcp_opts, 6) + 2 + if dnsopts >= 0 + memcpy(@localdns, @pkt->dhcp_opts.[dnsopts], IP4ADR_SIZE) + fin + break + otherwise + //dumpdhcp(pkt) + wend fin end // @@ -229,23 +207,23 @@ repeat // // Broadcast DHCP DISCOVER message // - optsOP.2 = DHCP_DISCOVER - optsIP:2 = 0 - optsIP:4 = 0 - optsSRV = 255 + optsOP.2 = DHCP_DISCOVER + optsIP:2 = 0 + optsIP:4 = 0 + optsSRV = 255 DHCP.dhcp_secs.1 = retry iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @optsSRV - @DHCP + 1) for timeout = 0 to 1000 iNet:serviceIP() - if optsOP.2 == DHCP_ACK - break + if optsOP.2 == DHCP_ACK + break fin next retry = retry + 1 until retry > 4 or optsOP.2 == DHCP_ACK iNet:closeUDP(portDHCP) iNet:setInterfaceIP(@localip, @localnet, @localgw) -puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln +//puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln iNet:setDNS(@localdns) -puts(@dnsstr);putip(@localdns);putln +//puts(@dnsstr);putip(@localdns);putln done diff --git a/src/libsrc/etherip.pla b/src/libsrc/etherip.pla index 500e22c..8d1b81a 100644 --- a/src/libsrc/etherip.pla +++ b/src/libsrc/etherip.pla @@ -1,27 +1,5 @@ include "inc/cmdsys.plh" -// -// Net object -// -import inet - word iNet -end -struc t_inet - word initIP - word serviceIP - word openUDP - word sendUDP - word closeUDP - word listenTCP - word connectTCP - word sendTCP - word closeTCP - word setInterfaceIP - word getInterfaceHA - word setDNS - word resolveIP - word setCallback - word setParam -end +include "inc/inet.plh" // // Predefine service routine // @@ -87,14 +65,14 @@ struc t_icmp word[2] icmp_header end // -// UDP IPv4 psuedo header +// UDP IPv4 pseudo header // struc t_piphdr byte[IP4ADR_SIZE] pip_src byte[IP4ADR_SIZE] pip_dst - byte pip_zero - byte pip_proto - word pip_len + byte pip_zero + byte pip_proto + word pip_len end // // UDP header @@ -117,19 +95,19 @@ end // // ARP packet // -const HW_ETHER = $0100 // BE format -const ARP_PROTO = $0008 // BE format -const ARP_REQST = $0100 // BE format -const ARP_REPLY = $0200 // BE format +const HW_ETHER = $0100 // BE format +const ARP_PROTO = $0008 // BE format +const ARP_REQST = $0100 // BE format +const ARP_REPLY = $0200 // BE format struc t_arp word arp_hw word arp_proto byte arp_hlen byte arp_plen word arp_op - byte[MAC_SIZE] arp_senderha + byte[MAC_SIZE] arp_senderha byte[IP4ADR_SIZE] arp_senderip - byte[MAC_SIZE] arp_targha + byte[MAC_SIZE] arp_targha byte[IP4ADR_SIZE] arp_targip end const t_earp = t_ethrhdr+t_arp @@ -152,14 +130,14 @@ word ePayload = PAYLOAD_ARP // // Pre-configured ARP packet - MUST follow ethernet header! // -word ARP = HW_ETHER // HW TYPE -word = ARP_PROTO // PROTO TYPE -byte = MAC_SIZE // HLEN +word ARP = HW_ETHER // HW TYPE +word = ARP_PROTO // PROTO TYPE +byte = MAC_SIZE // HLEN byte = IP4ADR_SIZE // PLEN -word opARP // OP -export byte[MAC_SIZE] localha +word opARP // OP +export byte[MAC_SIZE] localha export byte[IP4ADR_SIZE] localip -byte[MAC_SIZE] remoteha +byte[MAC_SIZE] remoteha byte[IP4ADR_SIZE] remoteip // // Local network parameters @@ -167,8 +145,8 @@ byte[IP4ADR_SIZE] remoteip byte[IP4ADR_SIZE] netmask byte[IP4ADR_SIZE] subnet byte[IP4ADR_SIZE] gateway -const MAX_UDP_NOTIFIES = 4 -const MAX_TCP_NOTIFIES = 4 +const MAX_UDP_NOTIFIES = 4 +const MAX_TCP_NOTIFIES = 4 // // Notify callbacks // @@ -191,64 +169,64 @@ word setFrameLen, writeFrame, getFrameLen, readFrame // Defines for ASM routines // asm equates - !SOURCE "vmsrc/plvmzp.inc" + !SOURCE "vmsrc/plvmzp.inc" end // // Swap bytes in word // asm swab - LDA ESTKL,X - LDY ESTKH,X - STA ESTKH,X - STY ESTKL,X - RTS + LDA ESTKL,X + LDY ESTKH,X + STA ESTKH,X + STY ESTKL,X + RTS end // // 1'S COMPLIMENT SUM BE format // sum1(PREVSUM, BUF, LEN) // asm sum1 - 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 - -CHKLP LDA (SRC),Y - PHA - INY - BNE + - INC SRCH -+ LDA (SRC),Y - ADC ESTKH+2,X - STA ESTKH+2,X - PLA - ADC ESTKL+2,X - STA ESTKL+2,X - INY - BNE + - INC SRCH -+ DEC ESTKL,X - BNE CHKLP - DEC ESTKH,X - BNE CHKLP - BCC + -- INC ESTKH+2,X - BNE + - INC ESTKL+2,X - BEQ - -+ INX - INX - RTS + 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 - +CHKLP LDA (SRC),Y + PHA + INY + BNE + + INC SRCH ++ LDA (SRC),Y + ADC ESTKH+2,X + STA ESTKH+2,X + PLA + ADC ESTKL+2,X + STA ESTKL+2,X + INY + BNE + + INC SRCH ++ DEC ESTKL,X + BNE CHKLP + DEC ESTKH,X + BNE CHKLP + BCC + +- INC ESTKH+2,X + BNE + + INC ESTKL+2,X + BEQ - ++ INX + INX + RTS end // // Send IP datagram @@ -268,34 +246,34 @@ def etherSendIP(ipdst, proto, seglist, size) hdr:ip_chksm = 0 memcpy(@hdr.ip_src, @localip, IP4ADR_SIZE) if !ipdst // IP_BROADCAST - memset(@hdr.ip_dst, IP_BROADCAST, IP4ADR_SIZE) + memset(@hdr.ip_dst, IP_BROADCAST, IP4ADR_SIZE) memset(@dstMAC, MAC_BROADCAST, MAC_SIZE) else if ipdst=>0 & netmask:0 <> subnet:0 or ipdst=>2 & netmask:2 <> subnet:2 ipdst = @gateway // External net destination - fin - memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE) + fin + memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE) retry = 0 while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2 - if retry >= 3 + if retry >= 3 return -1 // ARP failed - fin - retry = retry + 1 + fin + retry = retry + 1 memset(@dstMAC, MAC_BROADCAST, MAC_SIZE) - memset(@remoteha, 0, MAC_SIZE) - memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE) - ePayload = PAYLOAD_ARP - opARP = ARP_REQST - setFrameLen(t_earp) - writeFrame(@eFrame, t_earp) - for timeout = 1000 downto 0 - etherServiceIP - if remoteha:0 | remoteha:2 | remoteha:4 - break - fin - next - loop - memcpy(@dstMAC, @remoteha, MAC_SIZE) + memset(@remoteha, 0, MAC_SIZE) + memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE) + ePayload = PAYLOAD_ARP + opARP = ARP_REQST + setFrameLen(t_earp) + writeFrame(@eFrame, t_earp) + for timeout = 1000 downto 0 + etherServiceIP + if remoteha:0 | remoteha:2 | remoteha:4 + break + fin + next + loop + memcpy(@dstMAC, @remoteha, MAC_SIZE) fin // // Calculate checksum @@ -318,9 +296,9 @@ def etherSendIP(ipdst, proto, seglist, size) // Write the remaining segments // while size > 0 - writeFrame(seglist=>seg_buf, seglist=>seg_len) - size = size - seglist=>seg_len - seglist = seglist + t_segment + writeFrame(seglist=>seg_buf, seglist=>seg_len) + size = size - seglist=>seg_len + seglist = seglist + t_segment loop end // @@ -330,10 +308,10 @@ def etherSendUDP(port, ipdst, portdst, data, len) word[8] seglist // list of data and header segments byte[t_udphdr] hdr - hdr:udp_src = swab(port=>notify_port) - hdr:udp_dst = swab(portdst) - hdr:udp_len = swab(t_udphdr + len) - hdr:udp_chksm = 0 + hdr:udp_src = swab(port=>notify_port) + hdr:udp_dst = swab(portdst) + hdr:udp_len = swab(t_udphdr + len) + hdr:udp_chksm = 0 seglist:0:seg_buf = @hdr seglist:0:seg_len = t_udphdr seglist:4:seg_buf = data @@ -354,11 +332,11 @@ def etherOpenUDP(localport, callback, param) port = @portsUDP for i = 1 to MAX_UDP_NOTIFIES if port=>notify_port == localport - port=>notify_func = callback - port=>notify_parm = param - return port - fin - port = port + t_notify + port=>notify_func = callback + port=>notify_parm = param + return port + fin + port = port + t_notify next // // Add notification on localport if room @@ -366,12 +344,12 @@ def etherOpenUDP(localport, callback, param) port = @portsUDP for i = 1 to MAX_UDP_NOTIFIES if !port=>notify_port - port=>notify_port = localport - port=>notify_func = callback - port=>notify_parm = param - return port - fin - port = port + t_notify + port=>notify_port = localport + port=>notify_func = callback + port=>notify_parm = param + return port + fin + port = port + t_notify next end // @@ -382,13 +360,13 @@ def etherCloseUDP(port) byte i if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify) - // - // Clear notiications on this port - // - if port=>notify_port + // + // Clear notiications on this port + // + if port=>notify_port port=>notify_port = 0 - return 0 - fin + return 0 + fin fin // // Invalid port @@ -420,13 +398,13 @@ end // def etherSetCallback(port, callback) if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify) - // - // Update callback on this port - // - if port=>notify_port - port=>notify_func = callback - return 0 - fin + // + // Update callback on this port + // + if port=>notify_port + port=>notify_func = callback + return 0 + fin fin // // Invalid port @@ -438,13 +416,13 @@ end // def etherSetParam(port, param) if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify) - // - // Update callback on this port - // - if port=>notify_port - port=>notify_parm = param - return 0 - fin + // + // Update callback on this port + // + if port=>notify_port + port=>notify_parm = param + return 0 + fin fin // // Invalid port @@ -467,109 +445,109 @@ def etherServiceIP rxsize = getFrameLen() if rxsize // - // Read the entire packet into memory - // - rxpacket = heapalloc(rxsize) + // Read the entire packet into memory + // + rxpacket = heapalloc(rxsize) readFrame(rxpacket, rxsize) rxptr = rxpacket + t_ethrhdr - rxsize = rxsize - t_ethrhdr - // - // What kind of packet is it? - // - when rxpacket=>ethr_payload + rxsize = rxsize - t_ethrhdr + // + // What kind of packet is it? + // + when rxpacket=>ethr_payload is PAYLOAD_IP - iphdr = rxptr - rxptr = rxptr + t_iphdr - rxsize = rxsize - t_iphdr - if iphdr->ip_vers_hlen <> $45 - optlen = iphdr=>ip_vers_hlen - if optlen & $F0 <> $40 - // - // Not IPv4, ignore - // - break - fin - optlen = (optlen & $0F) << 2 - if optlen > t_iphdr - // - // Read the options and throw them on the ground! - // - rxptr = rxptr + (optlen - t_iphdr) - rxsize = rxsize - (optlen - t_iphdr) - fin - fin - // - // Filter valid destination address - // - if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy - if (iphdr=>ip_dst:0|netmask:0) & (iphdr=>ip_dst:2|netmask:2) <> IP_BROADCAST - break - fin - fin - // - // What kind of IP protocol is it? - // - when iphdr->ip_proto - is IP_PROTO_UDP - port = @portsUDP - if port - lclport = swab(rxptr=>udp_dst) - for i = 1 to MAX_UDP_NOTIFIES - if port=>notify_port == lclport - port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm) - break - fin - port = port + t_notify - next - fin - break - is IP_PROTO_TCP - break - is IP_PROTO_ICMP - // - // Service ICMP packets - // - if rxptr->icmp_type == ICMP_ECHO_REQST - if rxsize > 128 - echolen = 128 - else - echolen = rxsize - fin - memcpy(@echo_reply, rxptr, echolen) - echo_reply.icmp_type = ICMP_ECHO_REPLY - echo_reply:icmp_chksm = 0 - seglist:seg_buf = @echo_reply - seglist:seg_len = echolen - etherSendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen) - fin - if hookICMP - hookICMP(@iphdr=>ip_src, rxptr, rxsize) - fin - wend - break - is PAYLOAD_ARP - when rxptr=>arp_op - is ARP_REPLY - // - // Fill in ARP cache - // - memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip - break - is ARP_REQST - // - // Is this a request for me? - // - if rxptr=>arp_targip:0 == localip:0 and rxptr=>arp_targip:2 == localip:2 - memcpy(@dstMAC, @rxptr=>arp_senderha, MAC_SIZE) - memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip - ePayload = PAYLOAD_ARP - opARP = ARP_REPLY - setFrameLen(t_earp) - writeFrame(@eFrame, t_earp) - fin - wend + iphdr = rxptr + rxptr = rxptr + t_iphdr + rxsize = rxsize - t_iphdr + if iphdr->ip_vers_hlen <> $45 + optlen = iphdr=>ip_vers_hlen + if optlen & $F0 <> $40 + // + // Not IPv4, ignore + // + break + fin + optlen = (optlen & $0F) << 2 + if optlen > t_iphdr + // + // Read the options and throw them on the ground! + // + rxptr = rxptr + (optlen - t_iphdr) + rxsize = rxsize - (optlen - t_iphdr) + fin + fin + // + // Filter valid destination address + // + if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy + if (iphdr=>ip_dst:0|netmask:0) & (iphdr=>ip_dst:2|netmask:2) <> IP_BROADCAST + break + fin + fin + // + // What kind of IP protocol is it? + // + when iphdr->ip_proto + is IP_PROTO_UDP + port = @portsUDP + if port + lclport = swab(rxptr=>udp_dst) + for i = 1 to MAX_UDP_NOTIFIES + if port=>notify_port == lclport + port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm) + break + fin + port = port + t_notify + next + fin + break + is IP_PROTO_TCP + break + is IP_PROTO_ICMP + // + // Service ICMP packets + // + if rxptr->icmp_type == ICMP_ECHO_REQST + if rxsize > 128 + echolen = 128 + else + echolen = rxsize + fin + memcpy(@echo_reply, rxptr, echolen) + echo_reply.icmp_type = ICMP_ECHO_REPLY + echo_reply:icmp_chksm = 0 + seglist:seg_buf = @echo_reply + seglist:seg_len = echolen + etherSendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen) + fin + if hookICMP + hookICMP(@iphdr=>ip_src, rxptr, rxsize) + fin + wend + break + is PAYLOAD_ARP + when rxptr=>arp_op + is ARP_REPLY + // + // Fill in ARP cache + // + memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip + break + is ARP_REQST + // + // Is this a request for me? + // + if rxptr=>arp_targip:0 == localip:0 and rxptr=>arp_targip:2 == localip:2 + memcpy(@dstMAC, @rxptr=>arp_senderha, MAC_SIZE) + memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip + ePayload = PAYLOAD_ARP + opARP = ARP_REPLY + setFrameLen(t_earp) + writeFrame(@eFrame, t_earp) + fin + wend wend - heaprelease(rxpacket) + heaprelease(rxpacket) fin end // diff --git a/src/libsrc/fileio.pla b/src/libsrc/fileio.pla index 6ad9154..c837286 100644 --- a/src/libsrc/fileio.pla +++ b/src/libsrc/fileio.pla @@ -26,6 +26,7 @@ struc t_fileio word getpfx word setpfx word getfileinfo + word geteof word open word close word read @@ -36,13 +37,13 @@ struc t_fileio word readblock word writeblock end -predef a2getpfx, a23setpfx, a2getfileinfo, a2open, a23close +predef a2getpfx, a23setpfx, a2getfileinfo, a23geteof, a2open, a23close predef a23read, a2write, a2create, a23destroy predef a23newline, a2readblock, a2writeblock // // Exported function table. // -export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a2open, @a23close +export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2open, @a23close word = @a23read, @a2write, @a2create, @a23destroy word = @a23newline, @a2readblock, @a2writeblock // @@ -108,6 +109,19 @@ def a3getfileinfo(path, fileinfo) perr = syscall($C4, @params) return perr end +def a1geteof(refnum) + return 0 +end +def a23geteof(refnum) + byte params[6] + + params.0 = 2 + params.1 = refnum + params:2 = 0 + params:4 = 0 + syscall($D1, @params) + return params:2 +end def a1open(path) *CFFA1FileName = path return 0 @@ -273,6 +287,7 @@ when MACHID & $C8 fileio:getpfx = @a1getpfx fileio:setpfx = @a1setpfx fileio:getfileinfo = @a1getfileinfo + fileio:geteof = @a1geteof fileio:open = @a1open fileio:close = @a1close fileio:read = @a1read diff --git a/src/libsrc/inet.pla b/src/libsrc/inet.pla index 3930448..52a2557 100644 --- a/src/libsrc/inet.pla +++ b/src/libsrc/inet.pla @@ -1,6 +1,6 @@ include "inc/cmdsys.plh" // -// Net object +// iNet API - must match inet.plh // struc t_inet word initIP @@ -53,32 +53,32 @@ def iNetSetDNS(ipptr) return memcpy(@dns, ipptr, 4) end -def putb(hexb) - return call($FDDA, hexb, 0, 0, 0) -end -def puth(hex) - return call($F941, hex >> 8, hex, 0, 0) -end -def putip(ipptr) - byte i - - for i = 0 to 2 - puti(ipptr->[i]); putc('.') - next - return puti(ipptr->[i]) -end -def dumpbytes(buf, len) - word i - - for i = 0 to len - 1 - putb(buf->[i]) - if i & 7 == 7 - putln - else - putc(' ') - fin - next -end +//def putb(hexb) +// return call($FDDA, hexb, 0, 0, 0) +//end +//def puth(hex) +// return call($F941, hex >> 8, hex, 0, 0) +//end +//def dumpbytes(buf, len) +// word i +// +// for i = 0 to len - 1 +// putb(buf->[i]) +// if i & 7 == 7 +// putln +// else +// putc(' ') +// fin +// next +//end +//def putip(ipptr) +// byte i +// +// for i = 0 to 2 +// puti(ipptr->[i]); putc('.') +// next +// return puti(ipptr->[i]) +//end def parseIP(ipstr, ipaddr) byte i @@ -123,38 +123,38 @@ def recvDNS(remip, remport, pkt, len, ipaddr) if pkt=>dnsID == $BEEF q = pkt->dnsQdCount.1 r = pkt->dnsAnCount.1 + pkt->dnsNsCount.1 + pkt->dnsArCount.1 - resptr = pkt + t_dnshdr - while q - while ^resptr - //puts(resptr); putc('.') - resptr = resptr + ^resptr + 1 - loop - resptr = resptr + 1 - //putln; dumpbytes(resptr, 4); putln - resptr = resptr + 4 - q = q - 1 - loop - while r - //dumpbytes(resptr, 40); putln - if ^resptr & $C0 == $C0 - resptr = resptr + 2 - else - while ^resptr - //puts(resptr); putc('.') - resptr = resptr + ^resptr + 1 - loop - resptr = resptr + 1 - fin - if resptr->1 == 1 and resptr->3 == 1 and resptr->9 == 4 - ipaddr=>0 = resptr=>10 - ipaddr=>2 = resptr=>12 - fin - //putln; dumpbytes(resptr, 10); putc(':'); putln - resptr = resptr + 8 - //dumpbytes(resptr + 2, ^(resptr + 1)) - resptr = resptr + 2 + ^(resptr + 1); putln - r = r - 1 - loop + resptr = pkt + t_dnshdr + while q + while ^resptr + //puts(resptr); putc('.') + resptr = resptr + ^resptr + 1 + loop + resptr = resptr + 1 + //putln; dumpbytes(resptr, 4); putln + resptr = resptr + 4 + q-- + loop + while r + //dumpbytes(resptr, 40); putln + if ^resptr & $C0 == $C0 + resptr = resptr + 2 + else + while ^resptr + //puts(resptr); putc('.') + resptr = resptr + ^resptr + 1 + loop + resptr = resptr + 1 + fin + if resptr->1 == 1 and resptr->3 == 1 and resptr->9 == 4 + ipaddr=>0 = resptr=>10 + ipaddr=>2 = resptr=>12 + fin + //putln; dumpbytes(resptr, 10); putc(':'); putln + resptr = resptr + 8 + //dumpbytes(resptr + 2, ^(resptr + 1)) + resptr = resptr + 2 + ^(resptr + 1); putln + r = r - 1 + loop fin stateDNS = DNS_ANSWER end @@ -167,38 +167,38 @@ def iNetResolve(namestr, ipaddr) ipaddr=>2 = 0 if not parseIP(namestr, ipaddr) // - // Query Domain Name Server for address - // - dnspkt = heapmark // Use heap as working DNS query packet - msgptr = dnspkt - msgptr=>dnsID = $BEEF - msgptr=>dnsCode = $0001 // RD (Recursion Desired) - msgptr=>dnsQdCount = $0100 // BE count = 1 - msgptr=>dnsAnCount = 0 - msgptr=>dnsNsCount = 0 - msgptr=>dnsArCount = 0 - msgptr = parseDomain(namestr, msgptr + t_dnshdr) - msgptr=>0 = $0100 // BE TYPE = Address - msgptr=>2 = $0100 // BE CLASS = INternet - msglen = msgptr - dnspkt + 4 - heapalloc(msglen) - // - // Prepare to receive DNS answer from server - // - portDNS = iNet:openUDP(3999, @recvDNS, ipaddr) - // - // Service IP - // - stateDNS = DNS_QUERY - iNet:sendUDP(portDNS, @dns, 53, dnspkt, msglen) - for timeout = 1 to 1000 - iNet:serviceIP() - if stateDNS == DNS_ANSWER - break - fin - next - iNet:closeUDP(portDNS) - heaprelease(dnspkt) + // Query Domain Name Server for address + // + dnspkt = heapmark // Use heap as working DNS query packet + msgptr = dnspkt + msgptr=>dnsID = $BEEF + msgptr=>dnsCode = $0001 // RD (Recursion Desired) + msgptr=>dnsQdCount = $0100 // BE count = 1 + msgptr=>dnsAnCount = 0 + msgptr=>dnsNsCount = 0 + msgptr=>dnsArCount = 0 + msgptr = parseDomain(namestr, msgptr + t_dnshdr) + msgptr=>0 = $0100 // BE TYPE = Address + msgptr=>2 = $0100 // BE CLASS = INternet + msglen = msgptr - dnspkt + 4 + heapalloc(msglen) + // + // Prepare to receive DNS answer from server + // + portDNS = iNet:openUDP(3999, @recvDNS, ipaddr) + // + // Service IP + // + stateDNS = DNS_QUERY + iNet:sendUDP(portDNS, @dns, 53, dnspkt, msglen) + for timeout = 1 to 1000 + iNet:serviceIP() + if stateDNS == DNS_ANSWER + break + fin + next + iNet:closeUDP(portDNS) + heaprelease(dnspkt) fin return ipaddr=>0 <> 0 or ipaddr=>2 <> 0 end @@ -209,10 +209,10 @@ export def iNetInit // while ^driver //puts(driver);putln - if modexec(driver) >= 0 - break - fin - driver = driver + ^driver + 1 + if modexec(driver) >= 0 + break + fin + driver = driver + ^driver + 1 loop if !^driver return 0 @@ -228,7 +228,6 @@ end // // Fill iNet class // -iNet:initIP = @iNetInit -iNet:setDNS = @iNetSetDNS - +iNet:initIP = @iNetInit +iNet:setDNS = @iNetSetDNS done diff --git a/src/libsrc/uthernet.pla b/src/libsrc/uthernet.pla index 6340c2e..7d73522 100644 --- a/src/libsrc/uthernet.pla +++ b/src/libsrc/uthernet.pla @@ -9,11 +9,6 @@ import etherip predef setEtherDriver end // -// Module don't free memory -// -const modkeep = $2000 -const modinitkeep = $4000 -// // Uthernet register offsets // const TXDATA = $00 @@ -42,129 +37,129 @@ byte[6] utherMAC = $00,$0A,$99,$1E,$02,$A0 // Defines for ASM routines // asm equates - !SOURCE "vmsrc/plvmzp.inc" + !SOURCE "vmsrc/plvmzp.inc" end // // Uthernet I/O functions // asm _pokeiow - LDA ESTKL,X + LDA ESTKL,X end asm _pokeiowl - STA $C000 - LDA ESTKH,X + STA $C000 + LDA ESTKH,X end asm _pokeiowh - STA $C000 - RTS + STA $C000 + RTS end // // PEEK BYTE FROM I/O SPACE // _peekio() // asm _peekio - DEX + DEX end asm _peekiol - LDA $C000 - STA ESTKL,X - LDA #$00 - STA ESTKH,X - RTS + LDA $C000 + STA ESTKL,X + LDA #$00 + STA ESTKH,X + RTS end // // PEEK WORD FROM I/O SPACE // _peekiow() // asm _peekiow - DEX + DEX end asm _peekiowl - LDA $C000 - STA ESTKL,X + LDA $C000 + STA ESTKL,X end asm _peekiowh - LDA $C000 - STA ESTKH,X - RTS + LDA $C000 + STA ESTKH,X + RTS end // // WRITE FRAME DATA INTO I/O SPACE // pokefrm(BUF, LEN) // asm pokefrm - 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 + 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 + 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 + 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 - 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 - + 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 +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 ++ 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 @@ -205,12 +200,12 @@ def peekfrmlen 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 + len.1 = peekio(rxdata_hi) + len.0 = peekio(rxdata_lo) + else + peekio(rxdata_lo) + pokepreg($0102, $0140) // Skip pkt + fin fin return len end @@ -220,10 +215,10 @@ end for slot = $90 to $F0 step $10 if (peekiow(slot+TXCMD) & $CC3F) == $09 pokeiow(slot+PREG_INDEX, 0) - if peekiow(slot+PREG_DATA) == $630E + if peekiow(slot+PREG_DATA) == $630E pokepreg($0114, $40) // RESET - rxdata_hi = slot + 1 - txcmd = slot + TXCMD + rxdata_hi = slot + 1 + txcmd = slot + TXCMD txlen = slot + TXLEN isq = slot + INT_STATUS pregidx = slot + PREG_INDEX @@ -239,13 +234,13 @@ for slot = $90 to $F0 step $10 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) + // + // 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 diff --git a/src/libsrc/uthernet2.pla b/src/libsrc/uthernet2.pla index a201c30..ac86394 100644 --- a/src/libsrc/uthernet2.pla +++ b/src/libsrc/uthernet2.pla @@ -5,34 +5,7 @@ // layers, like the Uthernet // include "inc/cmdsys.plh" -// -// Net object -// -import inet - word iNet -end -struc t_inet - word initIP - word serviceIP - word openUDP - word sendUDP - word closeUDP - word listenTCP - word connectTCP - word sendTCP - word closeTCP - word setInterfaceIP - word getInterfaceHA - word setDNS - word resolveIP - word setCallback - word setParam -end -// -// Module don't free memory -// -const modkeep = $2000 -const modinitkeep = $4000 +include "inc/inet.plh" // // Wiznet registers // diff --git a/src/samplesrc/httpd.pla b/src/samplesrc/httpd.pla index 553d73f..9c30870 100644 --- a/src/samplesrc/httpd.pla +++ b/src/samplesrc/httpd.pla @@ -9,33 +9,11 @@ // still todo: output base filename for Content-Disposition header // include "inc/cmdsys.plh" -// -// Net object -// -import inet - word iNet -end -struc t_inet - word initIP - word serviceIP - word openUDP - word sendUDP - word closeUDP - word listenTCP - word connectTCP - word sendTCP - word closeTCP - word setInterfaceIP - word getInterfaceHA - word setDNS - word resolveIP - word setCallback - word setParam -end +include "inc/inet.plh" +include "inc/fileio.plh" word socketHTTP byte[65] prefix -byte perr word filebuff, iobuff byte fileInfo[12] = 0 // used for get_file_info() byte hello = "Apple II Web Server - 12 Nov 15\n" @@ -60,73 +38,6 @@ byte httpEnd = "\n\r\n\r" byte mimeTextHtml = "text/html" byte mimeOctetStream = "application/octet-stream" // -// ProDOS routines -// -def getpfx(path) - byte params[3] - - ^path = 0 - params.0 = 1 - params:1 = path - perr = syscall($C7, @params) - return path -end -def setpfx(path) - byte params[3] - - params.0 = 1 - params:1 = path - perr = syscall($C6, @params) - return path -end -def open(path, buff) - byte params[6] - - params.0 = 3 - params:1 = path - params:3 = buff - params.5 = 0 - perr = syscall($C8, @params) - return params.5 -end -def close(refnum) - byte params[2] - - params.0 = 1 - params.1 = refnum - perr = syscall($CC, @params) - return perr -end -def read(refnum, buff, len) - byte params[8] - - params.0 = 4 - params.1 = refnum - params:2 = buff - params:4 = len - params:6 = 0 - perr = syscall($CA, @params) - return params:6 -end -def get_eof(refnum) - byte params[5] - - params.0 = 2 - params.1 = refnum - params:2 = 0 - params.4 = 0 - syscall($D1, @params) - return params:2 -end -def get_file_info(path) - - fileInfo.0 = 10 // param count - fileInfo:1 = path // path name - - perr = syscall($C4, @fileInfo) - return perr -end -// // DEBUG // def putb(hexb) @@ -148,11 +59,11 @@ def dumpbytes(buf, len) for i = 0 to len - 1 putb(buf->[i]) - if i & 15 == 15 - putln - else - putc(' ') - fin + if i & 15 == 15 + putln + else + putc(' ') + fin next end def dumpchars(buf, len) @@ -187,13 +98,13 @@ end // def sendFile(fd, socket, len) while isuge(len, 1024) - read(fd, filebuff, 1024) - len = len - 1024 - iNet:sendTCP(socket, filebuff, 1024) + fileio:read(fd, filebuff, 1024) + len = len - 1024 + iNet:sendTCP(socket, filebuff, 1024) loop if len - read(fd, filebuff, len) - iNet:sendTCP(socket, filebuff, len) + fileio:read(fd, filebuff, len) + iNet:sendTCP(socket, filebuff, len) fin end // @@ -211,78 +122,78 @@ def servHTTP(remip, remport, lclport, data, len, param) if len > 0 //dumpchars(data, len) // - // Better be 'GET' - // + // Better be 'GET' + // if data->0 == 'G' and data->1 == 'E' and data->2 == 'T' and data->3 == ' ' - len = len - 1 - if len > 64 - len = 64 // maximum ProDOS path - fin + len = len - 1 + if len > 64 + len = 64 // maximum ProDOS path + fin for i = 4 to len // get ProDOS path from URL if data->[i] <= ' ' - data->3= i - 4 - url = data + 3 - if url->1 == '/' - if url->0 == 1 - url = @defhtml // Is this a directory with no file given? Use index.html - else - url->1 = url->0 - 1 - url = url + 1 - fin - fin - strcat(@filename, @prefix, url) - puts("GET:"); puts(@filename);putln - // - // Get file info - // - //puts("getting file info "); // debug - get_file_info(@filename) - refnum = open(@filename, iobuff) // try to open this file with ProDOS - if refnum // file was opened OK - filelen = get_eof(refnum) // get length of file for Content-Length - lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1) - strcat(@okhdr, @httpOK, @httpContentLen) - strcat(@okhdr, @okhdr, @lenstr) - strcat(@okhdr, @okhdr, "\n\r") - // - // Content type header - // - if fileInfo.4 == $03 OR fileInfo.4 == $04 - // - // this a text file - // - //puts(@mimeTextHtml) // debug - strcat(@okhdr, @okhdr, @httpContentType) - strcat(@okhdr, @okhdr, @mimeTextHtml) - else - // - // send as binary attachment - // - //puts(@mimeOctetStream) // debug - strcat(@okhdr, @okhdr, @httpContentType) - strcat(@okhdr, @okhdr, @mimeOctetStream) - strcat(@okhdr, @okhdr, "\n\r") - // - // and send filename too - // - strcat(@okhdr, @okhdr, @httpContentAttach) - // todo: get the base filename... - fin - strcat(@okhdr, @okhdr, @httpEnd) - //dumpchars(@okhdr + 1, okhdr) // debug - iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client - sendFile(refnum, socketHTTP, filelen) // send file data to client - close(refnum) - else // file couldn't be opened, so return 404 on this - puts("404 Not Found");putln // debug - iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND) - fin // if refnum - break // return - fin + data->3 = i - 4 + url = data + 3 + if url->1 == '/' + if url->0 == 1 + url = @defhtml // Is this a directory with no file given? Use index.html + else + url->1 = url->0 - 1 + url = url + 1 + fin + fin + strcat(@filename, @prefix, url) + puts("GET:"); puts(@filename);putln + // + // Get file info + // + //puts("getting file info "); // debug + fileio:getfileinfo(@filename) + refnum = fileio:open(@filename) // try to open this file with ProDOS + if refnum // file was opened OK + filelen = fileio:geteof(refnum) // get length of file for Content-Length + lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1) + strcat(@okhdr, @httpOK, @httpContentLen) + strcat(@okhdr, @okhdr, @lenstr) + strcat(@okhdr, @okhdr, "\n\r") + // + // Content type header + // + if fileInfo.4 == $03 OR fileInfo.4 == $04 + // + // this a text file + // + //puts(@mimeTextHtml) // debug + strcat(@okhdr, @okhdr, @httpContentType) + strcat(@okhdr, @okhdr, @mimeTextHtml) + else + // + // send as binary attachment + // + //puts(@mimeOctetStream) // debug + strcat(@okhdr, @okhdr, @httpContentType) + strcat(@okhdr, @okhdr, @mimeOctetStream) + strcat(@okhdr, @okhdr, "\n\r") + // + // and send filename too + // + strcat(@okhdr, @okhdr, @httpContentAttach) + // todo: get the base filename... + fin + strcat(@okhdr, @okhdr, @httpEnd) + //dumpchars(@okhdr + 1, okhdr) // debug + iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client + sendFile(refnum, socketHTTP, filelen) // send file data to client + fileio:close(refnum) + else // file couldn't be opened, so return 404 on this + puts("404 Not Found");putln // debug + iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND) + fin // if refnum + break // return + fin next - else - iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD) - fin + else + iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD) + fin fin socketHTTP = iNet:closeTCP(socketHTTP) end @@ -296,7 +207,7 @@ getpfx(@prefix) // Alloc aligned file/io buffers // filebuff = heapallocalign(1024, 8, 0) -iobuff = heapallocalign(1024, 8, 0) +//iobuff = heapallocalign(1024, 8, 0) // // Service IP //