tschak909 Posted January 13, 2022 Share Posted January 13, 2022 #FujiNet #ColecoAdam #CPM I can work with somebody to build bindings for their favorite language, e.g. Turbo PASCAL. Anyone want to jump in? All FujiNet networking functions can be done with writes to the correct AdamNet DCB, we just need a few bits of info, here's the data structure for a DCB in ? typedef struct _dcb { unsigned char status; // 1 void *buf; // 2 unsigned short len; // 2 unsigned long block; // 4 unsigned char unit; // 1 unsigned char reserved0; // 1 unsigned char reserved1; // 1 unsigned char reserved2; // 1 unsigned char reserved3; // 1 unsigned char reserved4; // 1 unsigned char reserved5; // 1 unsigned char dev; // 1 unsigned short max_len; // 2 unsigned char type; // 1 unsigned char dev_status; // 1 } DCB; // 21 bytes total And these exist contiguously immediately after the 4 bytes that comprise the PCB. One DCB for each device found on the AdamNet. Notable entries: * status - This does double duty, as both the status and command byte. You write the command, the Adam does the operation, and writes back a status sometime later. * buf - 16 bit memory address in Z80 space for the target operation * len - Length of I/O operation relative to the buffer. * block - Used by block devices to denote the desired 32-bit block address. * unit - logical unit number specified. * dev - The Adamnet node number for this device. (1 = keyboard, 2 = printer, etc.) * max_len - The maximum size of payload allowed for this device * type - Device type, 0 = character, 1 = block * dev_status - The 8-bit status byte returned in the last byte of a status packet. So all we have to do for a typical program is to: * Define a data structure that nicely maps a DCB * Find the DCB we want in memory by comparing against the dev entry until we find it. * Write to that section of memory any time we want something to happen for FujiNet * Periodically poll status to see when that operation is considered complete by the 6801. For MBASIC, I was able to do this with the following code: 64000 REM FUJINET ROUTINES 64010 REM ---------------- 64011 REM DCB FUNCS 64012 REM ---------------- 64020 DCBLEN=21:DCBEGIN=&HFEC4:DCBNUM=&HFEC3 64021 NET$=STRING$(255,0) 64022 STAT=1:WRI=3:REA=4 64030 DEF FN DCB(X)=X*DCBLEN+DCBEGIN 64040 DEF FN DCBSTATUS(X)=PEEK(FNDCB(X)) 64050 DEF FN DCBCMD(X)=FNDCB(X) 64060 DEF FN DCBBUFL(X)=FNDCB(X)+1 64061 DEF FN DCBBUFH(X)=FNDCB(X)+2 64070 DEF FN DCBDEVSTATUS(X)=PEEK(FNDCB(X)+20) 64080 DEF FN DCBDEV(X)=PEEK(FNDCB(X)+16) 64081 DEF FN DCBLENL(X)=FNDCB(X)+3 64082 DEF FN DCBLENH(X)=FNDCB(X)+4 64090 DEF FN DCBNUM(X)=PEEK(DCBNUM) The above sets up a nice little data structure that can easily traverse through the DCBs, finding them relative to the PCB at $FEC0. You can then find the correct DCB with the following code: 64093 REM -------- 64100 REM FIND DCB 64101 REM -------- 64110 FOR X=0 TO FNDCBNUM(0)-1 64120 IF FNDCBDEV(X)=9 THEN NET=X:RETURN 64130 NEXT X 64140 RETURN Where we look for the DCB that matches device ID 9, or the first network device, and if found, set NET to it. We can then send network operations with the following common code: 64150 REM -------------------- 64200 REM DO FUJINET OPERATION 64210 REM -------------------- 64220 GOSUB 64100:REM FIND DCB 64230 POKE FNDCBBUFL(NET),PEEK(VARPTR(NET$)+1) 64240 POKE FNDCBBUFH(NET),PEEK(VARPTR(NET$)+2) 64250 POKE FNDCBLENL(NET),PEEK(VARPTR(NET$)) 64260 POKE FNDCBLENH(NET),0 64270 POKE FNDCBCMD(NET),CMD 64280 IF FNDCBSTATUS(NET)<&H80 THEN GOTO 64280 64290 RETURN Because of the functions defined above, finding the correct addresses in memory is very easy, and we simply POKE the operation we want to do, taking special care to make sure that the very last byte written is the command (into the status/cmd byte!). After this, it's a simple matter of checking the status byte for the last bit set, to indicate that the command has completed. After this, doing FujiNet commands is as simple as: NET$="O"+CHR$(12)+CHR$(0)+"N:TCP://192.168.1.10:8080/":CMD=WRI:GOSUB 64200:REM OPEN NET$="WTHIS STRING GETS WRITTEN OUT."+CHR$(13):CMD=WRI:GOSUB 64200 REM WRITE NET$="C":CMD=WRI:GOSUB 64200:REM CLOSE NET$=STRING$(255,0):CMD=REA:GOSUB 64200:REM READ ANYTHING WAITING INTO NET$ and so on. Does this make sense? -Thom Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.