;===========================================================================
;                             cnetconfig
;===========================================================================
;
;  creates config file for cnet.devcie (in s:cnetdev.config)
;
;  NOTE: The file "s:config.dev" is used by cnet.device ONLY if it cannot
;        detect PCMCIA attribute memory ie. if the card did NOT power up
;        properly. Therefore cnetconfig should only be run when the card
;        IS working properly, so that a valid configuration can be saved!
;
; History:
;
; 8-7-97  v0.0 created by Bruce Abbott  (bhabbott@inhb.co.nz)
;
;

VERSION  = 0
REVISION = 0

 opt i+,d+

 output ram:cnetconfig


 include start.i    ; Amiga includes and startup code

 include pcmcia.i             ; card.resourse etc.
 include sanaii.i             ; the essential network stuff
 include cnet.i               ; CNet CN40BC hardware specs
 include printf.i


; flags

MYB_DEVOPENED = 0
MYB_CONSOLE   = 1


_main:
   move.l  WBenchMsg(pc),d0
   beq.s   .cli
   lea     consolename(pc),a0
   move.l  a0,d1
   move.l  #MODE_NEWFILE,d2
   dos     open                 ; open console window
   move.l  d0,ohandle
   bls     done
   bset    #MYB_CONSOLE,flags
   bra     .getdev
.cli:
   dos     output               ; get CLI output handle
   move.l  d0,ohandle
   beq     done
.getdev:
   move.l  execbase(pc),a3
   move.l  devicelist(a3),a0
   lea     devname(pc),a1
   exec    findname             ; find device in exec resident list
   move.l  d0,a2
   tst.l   d0
   bne     found
notfound:
   bsr     createport           ; create msgport for iorequest
   move.l  d0,port
   move.l  d0,a0
   move.l  #IOS2_SIZE,d0
   bsr     createio             ; create iorequest for opendev
   move.l  d0,ior
   move.l  ior(pc),a1
   lea     devname(pc),a0
   moveq   #0,d0
   moveq   #0,d1
   exec    opendevice           ; open "cnet.device" unit 0
   tst.l   d0
   beq.s   opened
   move.l  ior(pc),a1
   lea     fulldevname(pc),a0
   moveq   #0,d0
   moveq   #0,d1
   exec    opendevice           ; open "devs:networks/cnet.device"
   tst.l   d0
   beq.s   opened
   printf  <10,"Could not open '%s'!",10>,devname
   bra     done
opened:
   bset    #MYB_DEVOPENED,flags
   move.l  ior(pc),a1
   move.l  io_device(a1),a2
found:
   move.l  dd_cardres(a2),a6
   lea     dd_cardhandle(a2),a1
   lea     tuple(pc),a0
   moveq   #CISTPL_CONF_MAP,d1
   moveq   #40,d0
   jsr     _LVOCopyTuple(a6)            ; read config map tuple
   tst.l   d0
   beq     carderror
   moveq   #0,d3
   move.b  tuple+5(pc),d3
   lsl.w   #8,d3
   move.b  tuple+4(pc),d3
   printf  <10,"Configuration Register = $%04lx",10>,d3
   lea     dd_cardhandle(a2),a1
   lea     tuple(pc),a0
   moveq   #CISTPL_CONFIG,d1
   moveq   #40,d0
   jsr     _LVOCopyTuple(a6)            ; read 1st config tuple
   tst.l   d0
   beq     carderror
   moveq   #0,d4
   move.b  tuple+2(pc),d4
   and.b   #$3f,d4
   printf  <10,"Card Configuration ID  = $%02lx",10>,d4
   move.l  dd_romstationaddress(a2),d5
   moveq   #0,d6
   move.w  dd_romstationaddress+4(a2),d6
   printf  <10,"ROM Station Address    = %08lx%04lx",10,10>,d5,d6
   lea     filename(pc),a0
   move.l  a0,d1
   move.l  #MODE_NEWFILE,d2
   DOS     Open
   tst.l   d0
   ble     file_error
   move.l  ohandle(pc),d7                ; remember console output handle
   move.l  d0,ohandle
   printf  <"$%04lx=$%02lx",10,"@%08lx%04lx",10>,d3,d4,d5,d6
   move.l  ohandle(pc),d1
   DOS     Close
   move.l  d7,ohandle                    ; restore console output handle
   lea     filename(pc),a0
   printf  <10,"Created '%s'",10,10>,a0
   bra     done
file_error:
   lea     filename(pc),a0
   printf  <10,"Could NOT create '%s'!",10,10>,a0
   bra     done
carderror:
   printf  <10,10,"Warning: Attribute memory NOT detected!",10,10>
   move.l  dd_romstationaddress(a2),d4
   moveq   #0,d5
   move.w  dd_romstationaddress+4(a2),d5
   printf  <"ROM Station Address  = %08lx%04lx",10,10>,d4,d5
   move.l  dd_stationaddress(a2),d4
   moveq   #0,d5
   move.w  dd_stationaddress+4(a2),d5
   printf  <"Station Address used = %08lx%04lx",10,10>,d4,d5
done:
   btst    #MYB_DEVOPENED,flags(pc)
   beq.s   .devclosed
   move.l  ior(pc),a1
   exec    closedevice                   ; close device
.devclosed:
   move.l  ior(pc),a0
   move.l  #IOS2_SIZE,d0
   bsr     deleteio                      ; delete iorequest
   move.l  port(pc),a0
   bsr     deleteport                    ; delete msgport
   btst    #MYB_CONSOLE,flags(pc)
   beq.s   .noconsole
   move.l  #50*10,d1                     ; wait 10 seconds
   dos     delay
   move.l  ohandle(pc),d1
   dos     close                         ; close console window
.noconsole:
   moveq   #0,d0
   rts

;***********************************
;*  Create Signalling Message Port *
;***********************************
;
; Port = CreatePort()
;  d0
;
CreatePort:
  movem.l d2/a2,-(sp)
  moveq.l #-1,d0
  exec    AllocSignal
  move.l  d0,d2
  bmi.s   .error

  move.b  d0,d2
  moveq.l #MP_SIZE,d0
  move.l  #MEMF_PUBLIC|MEMF_CLEAR,d1
  exec    AllocMem
  move.l  d0,a2
  beq.s   .error

  sub.l   a1,a1
  exec    FindTask

  move.l  d0,MP_SIGTASK(a2)
  move.b  d2,MP_SIGBIT(a2)
  move.b  #NT_MSGPORT,LN_TYPE(a2)
  move.b  #PA_SIGNAL,MP_FLAGS(a2)
  lea     MP_MSGLIST(a2),a1

  move.l  a1,lh_head(a1)              ;Newlist a1
  addq.l  #4,lh_head(a1)
  clr.l   lh_tail(a1)
  move.l  a1,lh_tailpred(a1)
  move.l  a2,d0                       ; D0 = port
  bra.s   .done
.error:
  move.l  a2,a1
  bsr.s   DeletePort
  moveq   #0,d0
.done:
  movem.l (sp)+,d2/a2
  rts


;***************************
;*   Delete Message Port   *
;***************************
; DeletePort(port)
;             a0
;
DeletePort:
  move.l  a2,-(sp)
  move.l  a0,d0
  beq.s   .done
  move.l  d0,a1
  moveq   #0,d0
  move.b  MP_SIGBIT(a1),d0
  bmi.s   .nosignal
  move.l  a1,a2
  exec    FreeSignal
  move.l  a2,a1
.nosignal:
  moveq   #MP_SIZE,d0
  exec    FreeMem
.done:
  move.l (sp)+,a2
  rts



;********************************
;*     Create IORequest         *
;********************************
;
; ioreq = CreateIO(port,size)
;  d0               a0   d0
;
CreateIO:
  movem.l d2/a2,-(sp)
  move.l  a0,a2
  move.l  d0,d2
  move.l  #MEMF_PUBLIC|MEMF_CLEAR,d1
  exec    AllocMem
  tst.l   d0
  beq.s   .done
  move.l  d0,a0
  move.l  a2,MN_REPLYPORT(a0)
  move.b  #NT_MESSAGE,LN_TYPE(a0)
  move.w  d2,MN_LENGTH(a0)
.done:
  movem.l (sp)+,d2/a2
  rts


;*********************
;* Delete IO Request *
;*********************
;  DeleteIO(ioreq,size)
;             a0   d0
;
DeleteIO:
  move.l  a0,d1
  beq.s   .done
  move.l  d1,a1
  exec    FreeMem
.done:
  rts

port:
  dc.l 0

ior:
  dc.l 0

tuple:
  ds.b   48         ; buffer to read tuple into

flags:
  dc.b   0
  even

fulldevname:
 dc.b "devs:networks/"
devname:
 dc.b "cnet.device",0
 even

filename:
 dc.b  "s:cnetdev.config",0
 even

consolename:
 dc.b  "CON:60/60/480/120/ cnetconfig ",0
 even

 dc.b    "$VER: cnetconfig "
 dc.b    (VERSION+"0"),".",(REVISION+"0")," "
 dc.b    __DATE
 dc.b    " by Bruce Abbott (bhabbott@inhb.co.nz)",10,0
 even
