1. Interrupt driven serial read

Hi,

I tried to improve Serial.E V1.01 (C) 1997 from PJB Systems.

Unfortunately, I can't get it to work. If someone could have a look at the
code below and tell we what is wrong, it would be nice.

Jean-Marc

-- Start of code --

--
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
-- ³ Serial.E V1.01 (C) 1997 PJB Systems                   ³ Serial RS232
lib ³
--
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

global integer    PortIdx               PortIdx = 1
global integer    LocalEcho             LocalEcho = 0
global sequence   PortBase              PortBase = {#3F8,#2F8,#3E8,#2E8}

include Ports.E -- Come on RDS ! Even GWBASIC has I/O Access !!!
include machine.e

atom handlerA_address, handlerB_address
sequence usual_address
atom code_segment

-- record the values of the data segment and code segment
atom segment,  pointeur_ecr_2, pointeur_lect_2, tampon_rec_2
segment = allocate(4)
lock_memory(segment, 4)

pointeur_ecr_2 = allocate(4)
lock_memory(pointeur_ecr_2, 4)
poke4(pointeur_ecr_2, 0)

pointeur_lect_2 = allocate(4)
lock_memory(pointeur_lect_2, 4)
poke4(pointeur_lect_2, 0)

tampon_rec_2 = allocate(1024)
lock_memory(tampon_rec_2, 1024)
mem_set(tampon_rec_2, 0, 1024)

sequence save_segment_code
save_segment_code = {
    #53,   -- push ebx
    #0E,   -- push cs   or #1E push ds -- only a 16-bit value
    #5B,   -- pop ebx
    #89, #1D} & int_to_bytes(segment) & -- mov segment, ebx
    {#5B,   -- pop ebx
    #C3    -- ret
}
-- note: there's no "pop cs" instruction

atom save_segment
save_segment = allocate(length(save_segment_code))
poke(save_segment, save_segment_code)
call(save_segment) -- save code segment

-- N.B. Only read the low order two bytes! - See data segment below
code_segment = peek(segment) + 256 * peek(segment+1)

poke(save_segment+1, #1E)
call(save_segment) -- save data segment

sequence GetSerialByte
GetSerialByte = {
  #1E,       -- push ds
  #60,       -- pushad
  -- restore our data segment value:
  #BB} & peek({segment, 2}) & {0,0} & -- mov ebx, data segment value
  {#53,       -- push ebx
  #1F,       -- pop ds

  #FB,                                                -- sti
  #BA,#F8,#02,0,0,                                -- mov edx,0x2f8
  #EC,                                                -- in al,dx
  #8B,#3E} & int_to_bytes(pointeur_ecr_2) & {        -- mov
di,pointeur_ecr_2
  #88,#85} & int_to_bytes(tampon_rec_2) & {        -- mov
[di+tampon_rec_2],al
  #A1} & int_to_bytes(pointeur_ecr_2) & {        -- mov ax,pointeur_ecr_2
  #99,                                                -- cwd
  #B9,#00,#04,                                        -- mov cx,0x400
  #F7,#F9,                                        -- idiv cx
  #92,                                                -- xchg ax,dx
  #40,                                                -- inc ax
  #A3} & int_to_bytes(pointeur_ecr_2) & {        -- mov pointeur_ecr_2,ax
  #A1} & int_to_bytes(pointeur_ecr_2) & {        -- mov ax,pointeur_ecr_2
  #3B,#06} & int_to_bytes(pointeur_lect_2) & {        -- cmp
ax,pointeur_lect_2
  #75,#12,                                        -- jnz #12
  #A1} & int_to_bytes(pointeur_lect_2) & {        -- mov ax,pointeur_lect_2
  #99,                                                -- cwd
  #B9,#00,#04,                                        -- mov cx,0x400
  #F7,#F9,                                        -- idiv cx
  #92,                                                -- xchg ax,dx
  #40,                                                -- inc ax
  #A3} & int_to_bytes(pointeur_lect_2) & {        -- mov pointeur_lect_2,ax
  #B0,#20,                                        -- mov al,0x20
  #E6,#20,                                        -- out 0x20,al

  #61,       -- popad
  #1F,       -- pop ds
  #CF        -- iretd  -- return from interrupt
}

atom InputAsm
sequence OrigVector
integer HookInstalled

HookInstalled = 0

global procedure InitCom2()
-- init code space for assembler routine

  if HookInstalled then
    return
  end if

  InputAsm = allocate(length(GetSerialByte))
  lock_memory(InputAsm, length(GetSerialByte))
  if not InputAsm then
    puts(1,"Not enough memory !\n")
    abort(1)
  end if
  OrigVector = get_vector(#0B)
  poke(InputAsm,GetSerialByte)

  set_vector(#0B,{code_segment,InputAsm})
  HookInstalled = 1
end procedure -- InitCom2()

global procedure FreeCom2()
-- free memory occupied by assembler routines

  if not HookInstalled then
     return
  end if

  set_vector(#0B,OrigVector)
  free(InputAsm)

  HookInstalled = 0
end procedure -- FreeCom2()

integer diff
diff = -1

global function ReadPending()
integer plect, pecr
  if not HookInstalled then
    return -1
  end if
  plect = peek4u(pointeur_lect_2)
  pecr = peek4u(pointeur_ecr_2)

  if (plect-pecr) != diff then
    printf(1,"Plect = %d, Pecr= %d\n",{plect, pecr})
    diff = plect - pecr
  end if

  if pecr > plect then
    return 1024 + plect - pecr
  else
    return plect - pecr
  end if
end function

global function Com2Read()
  if not HookInstalled then
    return -1
  end if
  return peek4u(tampon_rec_2+pointeur_lect_2)
end function

global procedure SendSerialByte(integer p,integer b)
  integer addr, lsr, ecd

  if (p > 0) and (p < 5) then
    if (b >= 0) and (b < 256) then
      addr = PortBase[p]
      ecd = 1000
      lsr = 0
      while (lsr = 0) and (ecd > 0) do
        lsr = and_bits(Input(addr + 5),64)
        ecd = ecd - 1
      end while
      Output(b,addr)
    end if
  end if
end procedure


global function GetPortBPDS(integer port)
  integer addr,dlab,baud, dvsr,tmp1,tmp2,parity,data,stop

  addr = PortBase[port]

  dlab = Input(addr + 3)
  tmp1 = dlab

  dlab = or_bits(dlab,#80)
  Output(dlab,addr + 3)

  dvsr = Input(addr) + (Input(addr + 1) * 256)

  dlab = and_bits(dlab,#7F)
  Output(dlab,addr + 3)

  if dvsr > 0 then
    baud = floor(115200 / dvsr)
  else
    baud = 0
  end if

  tmp2 = and_bits(tmp1,#38)
  parity = tmp2
  if tmp2 = 8 then
    parity = -1
  elsif tmp2 = 24 then
    parity = 1
  end if

  if and_bits(tmp1,4) > 0 then
    stop = 2
  else
    stop = 1
  end if

  data = and_bits(tmp1,3) + 5

  return {baud,parity,data,stop}
end function

global procedure SetPortBPDS
  (integer port,integer baud,integer parity,integer data, integer stop)
  integer ok,addr, dlab, dvsr, dl, dh, p, s

  ok = 1
  if (port < 1) or (port > 4) then ok= 0 end if
  if (baud < 75) or (baud > 115200) then ok = 0 end if
  if (data < 5) or (data > 8) then ok = 0 end if
  if (stop < 1) or (stop > 2) then ok = 0 end if

  if ok > 0 then
    dvsr = floor(115200 / baud)
    dl = and_bits(#FF,dvsr)
    dh = floor(dvsr / 256)

    addr = PortBase[port]

    p = 0
    if parity > 0 then
      p = 24
    elsif parity < 0 then
      p = 8
    end if

    s = 0
    if stop = 2 then
      s = 4
    end if

    dlab = #80 + p + s + (data - 5)
    Output(dlab,addr + 3)

    Output(dl,addr)
    Output(dh,addr + 1)

    dlab = and_bits(dlab,#7F)
    Output(dlab,addr + 3)
  end if
end procedure

-- End of code --

-- Main program --

--
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
¿
-- ³ E-Term.EX V1.01 by PJB Systems
³
--
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Ù

include Serial2.E

integer Port,Baud,Parity,Data,Stop,rx,tx,rcnt
sequence rbuff  rbuff = {}
sequence BPDS

Port = 2 -- Change this if you like to 1, 2, 3 or 4

InitCom2()
puts(1,"Interrupt handler initiated !\n")

SetPortBPDS(Port,9600,0,8,1) -- You can change the baud,parity,data & stop
--          ³    ³    ³ ³ ÀÄÄÄÄ Stop bit 1 or 2
--          ³    ³    ³ ÀÄÄÄÄÄÄ Data bits 5,6,7 & 8
--          ³    ³    ÀÄÄÄÄÄÄÄÄ Parity 0 = None, 1 = Even, -1 = Odd
--          ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄ Baud rate 75 ~ 115200
--          ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Port COM1: to COM4:

tx = 0
while tx != 27 do
  if ReadPending()>0 then
    rx = Com2Read()
    if rx >= 0 then -- Catch data as it comes in
      printf(1,"%s",{rx})
    end if
  end if

  tx = get_key() -- Get key presses
  if tx > 0 then -- Send key
    SendSerialByte(Port,tx)
  end if
end while

FreeCom2()
puts(1,"Bye.\n")

new topic     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu