First sighting of life from drivewire.
authorNeal Andrew Crook <neal@pippaluk.org.uk>
Fri, 29 Jul 2016 22:31:09 +0000 (23:31 +0100)
committerNeal Andrew Crook <neal@pippaluk.org.uk>
Fri, 29 Jul 2016 22:31:09 +0000 (23:31 +0100)
Kernel/platform-multicomp09/README
Kernel/platform-multicomp09/devtty.c
Kernel/platform-multicomp09/drivewire.s
Kernel/platform-multicomp09/dwread.s
Kernel/platform-multicomp09/dwwrite.s

index d6edb0f..d0466a5 100644 (file)
@@ -19,10 +19,16 @@ provides the following:
   - I/O space from 0xffd0-0xffdf
 - 50Hz Timer interrupt
 - Hardware single-step
+  - NMI is devoted to this function. See source code of "Buggy" for
+  details.
 - SD controller in hw state-machines
 - Virtual 6850-like UART interfacing to an 80x25 colour ANSI terminal
   on a VGA display with PS/2 keyboard input
-- Upto 2 6850-like serial UARTs with RS232 or virtual-RS232/USB interfaces
+- 2 6850-like serial UARTs with RS232 or virtual-RS232/USB interfaces.
+  The baud rate is hard-wired (in Microcomputer.vhd) to 115,200 which
+  suits DriveWire perfectly.
+- Jumper to swap (in hardware) addresses of Virtual UART and actual
+  UART, allowing the boot device to be swapped.
 - coco-style memory mapping unit (2 contexts, 8K banks)
   - upto 1MByte physical RAM
 - RTC through DS1302 bit-banged on GPIO port.
@@ -127,7 +133,7 @@ DEVICES (so far)
 node       major   minor     description
 /dev/tty1  2       1                VGA/PS2 console  <-+-- swappable by VDUFFD0
 /dev/tty2  2       2         RS232 port       <-+             jumper
-/dev/tty3  2       3         USB virtual RS232 port
+/dev/tty3  2       3         RS232 port for Drivewire transport to server
 /dev/tty4  2       4         Drivewire Virtual Window #0  (coming soon..)
 /dev/dw?   8       0-256     Drivewire Block Drives       (coming soon..)
 
index 0d68e42..247c4a0 100644 (file)
    Port 0 and Port 1 mappings can be swapped through a jumper on the PCB.
    Port 2 is a serial port.
 
-   Port 0 is used for tty1, Port 1 for tty2.
+   Port 0 is used for tty1, Port 1 for tty2. Port2 is dedicated to DriveWire.
 */
 static uint8_t *uart[] = {
        0,      0,                               /* Unused */
        (uint8_t *)0xFFD1, (uint8_t *)0xFFD0,    /* Virtual UART Data, Status port0, tty1 */
        (uint8_t *)0xFFD3, (uint8_t *)0xFFD2,    /*         UART Data, Status port1, tty2 */
-       (uint8_t *)0xFFD5, (uint8_t *)0xFFD4,    /*         UART Data, Status port2, tty3 */
+       (uint8_t *)0xFFD5, (uint8_t *)0xFFD4,    /*         UART Data, Status port2, dw   */
 };
 
 #ifdef MC09_VIRTUAL_IN
@@ -58,15 +58,14 @@ uint8_t vtattr_cap;
 
 uint8_t tbuf1[TTYSIZ];   /* virtual serial port 0: console */
 uint8_t tbuf2[TTYSIZ];   /*         serial port 1: UART */
-uint8_t tbuf3[TTYSIZ];   /*         serial port 2: UART */
-uint8_t tbuf4[TTYSIZ];   /* drivewire VSER 0 */
-uint8_t tbuf5[TTYSIZ];   /* drivewire VSER 1 */
-uint8_t tbuf6[TTYSIZ];   /* drivewire VSER 2 */
-uint8_t tbuf7[TTYSIZ];   /* drivewire VSER 3 */
-uint8_t tbuf8[TTYSIZ];   /* drivewire VWIN 0 */
-uint8_t tbuf9[TTYSIZ];   /* drivewire VWIN 1 */
-uint8_t tbufa[TTYSIZ];   /* drivewire VWIN 2 */
-uint8_t tbufb[TTYSIZ];   /* drivewire VWIN 3 */
+uint8_t tbuf3[TTYSIZ];   /* drivewire VSER 0 */
+uint8_t tbuf4[TTYSIZ];   /* drivewire VSER 1 */
+uint8_t tbuf5[TTYSIZ];   /* drivewire VSER 2 */
+uint8_t tbuf6[TTYSIZ];   /* drivewire VSER 3 */
+uint8_t tbuf7[TTYSIZ];   /* drivewire VWIN 0 */
+uint8_t tbuf8[TTYSIZ];   /* drivewire VWIN 1 */
+uint8_t tbuf9[TTYSIZ];   /* drivewire VWIN 2 */
+uint8_t tbufa[TTYSIZ];   /* drivewire VWIN 3 */
 
 
 struct s_queue ttyinq[NUM_DEV_TTY + 1] = {
@@ -75,17 +74,16 @@ struct s_queue ttyinq[NUM_DEV_TTY + 1] = {
        /* Virtual UART/Real UART Consoles */
        {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2},
-       {tbuf3, tbuf3, tbuf3, TTYSIZ, 0, TTYSIZ / 2},
        /* Drivewire Virtual Serial Ports */
+       {tbuf3, tbuf3, tbuf3, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf4, tbuf4, tbuf4, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf5, tbuf5, tbuf5, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf6, tbuf6, tbuf6, TTYSIZ, 0, TTYSIZ / 2},
-       {tbuf7, tbuf7, tbuf7, TTYSIZ, 0, TTYSIZ / 2},
        /* Drivewire Virtual Window Ports */
+       {tbuf7, tbuf7, tbuf7, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf8, tbuf8, tbuf8, TTYSIZ, 0, TTYSIZ / 2},
        {tbuf9, tbuf9, tbuf9, TTYSIZ, 0, TTYSIZ / 2},
        {tbufa, tbufa, tbufa, TTYSIZ, 0, TTYSIZ / 2},
-       {tbufb, tbufa, tbufa, TTYSIZ, 0, TTYSIZ / 2},
 };
 
 
@@ -93,7 +91,7 @@ struct s_queue ttyinq[NUM_DEV_TTY + 1] = {
 /* A wrapper for tty_close that closes the DW port properly */
 int my_tty_close(uint8_t minor)
 {
-       if (minor > 3 && ttydata[minor].users == 1)
+       if (minor > 2 && ttydata[minor].users == 1)
                dw_vclose(minor);
        return (tty_close(minor));
 }
@@ -121,8 +119,9 @@ void kputchar(char c)
 
 ttyready_t tty_writeready(uint8_t minor)
 {
+       // [NAC HACK 2016Jul27] do I need to wait for the DW uart? Maybe I do..
        uint8_t c;
-        if ((minor < 1) || (minor > 3)) {
+        if ((minor < 1) || (minor > 2)) {
                return TTY_READY_NOW;
         }
        c = *(uart[minor*2 + 1]); /* 2 entries per UART, +1 to get STATUS */
@@ -131,10 +130,10 @@ ttyready_t tty_writeready(uint8_t minor)
 
 void tty_putc(uint8_t minor, unsigned char c)
 {
-       if ((minor > 0) && (minor < 4)) {
+       if ((minor > 0) && (minor < 3)) {
                *(uart[minor*2]) = c; /* UART Data */
        }
-       if (minor > 3 ) {
+       if (minor > 2 ) {
                dw_putc(minor, c);
        }
 }
@@ -147,7 +146,7 @@ void tty_sleeping(uint8_t minor)
 
 void tty_setup(uint8_t minor)
 {
-       if (minor > 3) {
+       if (minor > 2) {
                dw_vopen(minor);
                return;
        }
@@ -191,9 +190,7 @@ void platform_interrupt(void)
        c = *(uart[1*2 + 1]);
        if (c & 0x01) { tty_inproc(1, *(uart[1*2])); }
        /*      c = *(uart[2*2 + 1]);
-       if (c & 0x01) { tty_inproc(2, *(uart[2*2])); }
-       c = *(uart[3*2 + 1]);
-       if (c & 0x01) { tty_inproc(3, *(uart[3*2])); } */
+       if (c & 0x01) { tty_inproc(2, *(uart[2*2])); } */
 #endif
 
        c = timer_reg;
@@ -202,7 +199,7 @@ void platform_interrupt(void)
                timer_interrupt();   /* tell the OS it happened */
        }
 
-        //     dw_vpoll();
+       dw_vpoll();
 }
 
 
index 214d468..e8c1d60 100644 (file)
@@ -160,11 +160,11 @@ ReadEx     puls  d,x,y,pc
 
 ; Used by DWRead and DWWrite
 IntMasks equ   $50
-NOINTMASK equ  1
+NOINTMASK equ  0
 
 ; Hardcode these for now so that we can use below files unmodified
 H6309    equ 0
-BECKER   equ 1
+BECKER   equ 0
 ARDUINO  equ 0
 JMCPBCK  equ 0
 BAUD38400 equ 0
index 1b4c587..77d39aa 100644 (file)
 *******************************************************
 *
-* Copied from HDB-DOS from toolshed.sf.net
+* Derived from HDB-DOS from toolshed.sf.net
 * The original code is public domain
 *
 * DWRead
 *    Receive a response from the DriveWire server.
 *    Times out if serial port goes idle for more than 1.4 (0.7) seconds.
 *    Serial data format:  1-8-N-1
-*    4/12/2009 by Darren Atkinson
+*    28Jul2106 by Neal Crook for Multicomp UART
 *
 * Entry:
 *    X  = starting address where data is to be stored
 *    Y  = number of bytes expected
 *
 * Exit:
-*    CC = carry set on framing error, Z set if all bytes received
+*    CC = Carry set on framing error, Z set if all bytes received
 *    X  = starting address of data received
 *    Y  = checksum
 *    U is preserved.  All accumulators are clobbered
 *
+* [NAC HACK 2016Jul29] assume: timeout indicated by C=0, Z=0
+*
+          include "platform.def"        ; makes ports available to dwread, dwwrite
 
-          IFNE ARDUINO
-* Note: this is an optimistic routine. It presumes that the server will always be there, and
-* has NO timeout fallback. It is also very short and quick.
-DWRead    clra                          ; clear Carry (no framing error)
-          pshs   u,x,cc              ; preserve registers
-          leau   ,x
-          ldx    #$0000
-loop@     tst    $FF51                  ; check for CA1 bit (1=Arduino has byte ready)
-          bpl    loop@                  ; loop if not set
-          ldb    $FF50                  ; clear CA1 bit in status register
-          stb    ,u+                    ; save off acquired byte
-          abx                           ; update checksum
-          leay   ,-y
-          bne    loop@
-
-          leay      ,x                  ; return checksum in Y
-          puls      cc,x,u,pc        ; restore registers and return
-
-          ELSE
-
-          IFNE JMCPBCK
-* NOTE: There is no timeout currently on here...
-DWRead    clra                          ; clear Carry (no framing error)
-          deca                          ; clear Z flag, A = timeout msb ($ff)
-          tfr       cc,b
-          pshs      u,x,dp,b,a          ; preserve registers, push timeout msb
-          leau   ,x
-          ldx    #$0000
-          IFEQ   NOINTMASK
-          orcc   #IntMasks
-          ENDC
-loop@     ldb    $FF4C
-          bitb   #$02
-          beq    loop@
-          ldb    $FF44
-          stb    ,u+
-          abx
-          leay   ,-y
-          bne    loop@
-
-          tfr    x,y
-          ldb    #0
-          lda    #3
-          leas      1,s                 ; remove timeout msb from stack
-          inca                          ; A = status to be returned in C and Z
-          ora       ,s                  ; place status information into the..
-          sta       ,s                  ; ..C and Z bits of the preserved CC
-          leay      ,x                  ; return checksum in Y
-          puls      cc,dp,x,u,pc        ; restore registers and return
-          ELSE
-          IFNE BECKER
-          IFNDEF BCKSTAT
-BCKSTAT   equ   $FF41
-          ENDC
-          IFNDEF BCKPORT
-BCKPORT   equ   $FF42
-          ENDC
-* NOTE: There is no timeout currently on here...
-DWRead    clra                          ; clear Carry (no framing error)
-          deca                          ; clear Z flag, A = timeout msb ($ff)
-          tfr       cc,b
-          pshs      u,x,dp,b,a          ; preserve registers, push timeout msb
-          leau   ,x
-          ldx    #$0000
-          IFEQ   NOINTMASK
-          orcc   #IntMasks
-          ENDC
-loop@     ldb    BCKSTAT
-          bitb   #$02
-          beq    loop@
-          ldb    BCKPORT
-          stb    ,u+
-          abx
-          leay   ,-y
-          bne    loop@
-          tfr    x,y
-          ldb    #0
-          lda    #3
-timeout   leas      1,s                 ; remove timeout msb from stack
-          inca                          ; A = status to be returned in C and Z
-          ora       ,s                  ; place status information into the..
-          sta       ,s                  ; ..C and Z bits of the preserved CC
-          leay      ,x                  ; return checksum in Y
-          puls      cc,dp,x,u,pc        ; restore registers and return
-          ENDC
-          ENDC
-          ENDC
-
-          IFEQ BECKER+JMCPBCK+ARDUINO
-          IFNE BAUD38400
 *******************************************************
-* 38400 bps using 6809 code and timimg
+* 57600 (115200) bps using 6809 code and hw UART
 *******************************************************
 
 DWRead    clra                          ; clear Carry (no framing error)
           deca                          ; clear Z flag, A = timeout msb ($ff)
           tfr       cc,b
-          pshs      u,x,dp,b,a          ; preserve registers, push timeout msb
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-          tfr       a,dp                ; set direct page to $FFxx
-          setdp     $ff
-          leau      ,x                  ; U = storage ptr
-          ldx       #0                  ; initialize checksum
-          adda      #2                  ; A = $01 (serial in mask), set Carry
+          pshs      u,x,b,a            ; preserve registers, push timeout msb
 
-* Wait for a start bit or timeout
-rx0010    bcc       rxExit              ; exit if timeout expired
-          ldb       #$ff                ; init timeout lsb
-rx0020    bita      <BBIN               ; check for start bit
-          beq       rxByte              ; branch if start bit detected
-          subb      #1                  ; decrement timeout lsb
-          bita      <BBIN
-          beq       rxByte
-          bcc       rx0020              ; loop until timeout lsb rolls under
-          bita      <BBIN
-          beq       rxByte
-          addb      ,s                  ; B = timeout msb - 1
-          bita      <BBIN
-          beq       rxByte
-          stb       ,s                  ; store decremented timeout msb
-          bita      <BBIN
-          bne       rx0010              ; loop if still no start bit
+* stack now looks like this:
+* PCL PCH UL UH XL XH B A
+* at exit, A will be discarded. B is a "clean" version of CC
+* (!Z and !C) and will be popped into CC.
 
-* Read a byte
-rxByte    leay      ,-y                 ; decrement request count
-          ldd       #$ff80              ; A = timeout msb, B = shift counter
-          sta       ,s                  ; reset timeout msb for next byte
-rx0030    exg       a,a
-          nop
-          lda       <BBIN               ; read data bit
-          lsra                          ; shift into carry
-          rorb                          ; rotate into byte accumulator
-          lda       #$01                ; prep stop bit mask
-          bcc       rx0030              ; loop until all 8 bits read
-
-          stb       ,u+                 ; store received byte to memory
-          abx                           ; update checksum
-          ldb       #$ff                ; set timeout lsb for next byte
-          anda      <BBIN               ; read stop bit
-          beq       rxExit              ; exit if framing error
-          leay      ,y                  ; test request count
-          bne       rx0020              ; loop if another byte wanted
-          lda       #$03                ; setup to return SUCCESS
-
-* Clean up, set status and return
-rxExit    leas      1,s                 ; remove timeout msb from stack
-          inca                          ; A = status to be returned in C and Z
-          ora       ,s                  ; place status information into the..
-          sta       ,s                  ; ..C and Z bits of the preserved CC
-          leay      ,x                  ; return checksum in Y
-          puls      cc,dp,x,u,pc        ; restore registers and return
-          setdp     $00
-
-
-          ELSE
-          IFNE H6309
-*******************************************************
-* 57600 (115200) bps using 6309 native mode
-*******************************************************
-
-DWRead    clrb                          ; clear Carry (no framing error)
-          decb                          ; clear Z flag, B = $FF
-          pshs      u,x,dp,cc           ; preserve registers
-          IFEQ      NOINTMASK
+         IFEQ      NOINTMASK
           orcc      #IntMasks           ; mask interrupts
           ENDC
-*         ldmd      #1                  ; requires 6309 native mode
-          tfr       b,dp                ; set direct page to $FFxx
-          setdp     $ff
-          leay      -1,y                ; adjust request count
-          leau      ,x                  ; U = storage ptr
-          tfr       0,x                 ; initialize checksum
-          lda       #$01                ; A = serial in mask
-          bra       rx0030              ; go wait for start bit
-
-* Read a byte
-rxByte    sexw                          ; 4 cycle delay
-          ldw       #$006a              ; shift counter and timing flags
-          clra                          ; clear carry so next will branch
-rx0010    bcc       rx0020              ; branch if even bit number (15 cycles)
-          nop                           ; extra (16th) cycle
-rx0020    lda       <BBIN               ; read bit
-          lsra                          ; move bit into carry
-          rorb                          ; rotate bit into byte accumulator
-          lda       #0                  ; prep A for 8th data bit
-          lsrw                          ; bump shift count, timing bit to carry
-          bne       rx0010              ; loop until 7th data bit has been read
-          incw                          ; W = 1 for subtraction from Y
-          inca                          ; A = 1 for reading bit 7
-          anda      <BBIN               ; read bit 7
-          lsra                          ; move bit 7 into carry, A = 0
-          rorb                          ; byte is now complete
-          stb       ,u+                 ; store received byte to memory
-          abx                           ; update checksum
-          subr      w,y                 ; decrement request count
-          inca                          ; A = 1 for reading stop bit
-          anda      <BBIN               ; read stop bit
-          bls       rxExit              ; exit if completed or framing error
-
-* Wait for a start bit or timeout
-rx0030    clrw                          ; initialize timeout counter
-rx0040    bita      <BBIN               ; check for start bit
-          beq       rxByte              ; branch if start bit detected
-          addw      #1                  ; bump timeout counter
-          bita      <BBIN
-          beq       rxByte
-          bcc       rx0040              ; loop until timeout rolls over
-          lda       #$03                ; setup to return TIMEOUT status
-
-* Clean up, set status and return
-rxExit    beq       rx0050              ; branch if framing error
-          eora      #$02                ; toggle SUCCESS flag
-rx0050    inca                          ; A = status to be returned in C and Z
-          ora       ,s                  ; place status information into the..
-          sta       ,s                  ; ..C and Z bits of the preserved CC
-          leay      ,x                  ; return checksum in Y
-          puls      cc,dp,x,u,pc        ; restore registers and return
-          setdp     $00
-
-
-          ELSE
-*******************************************************
-* 57600 (115200) bps using 6809 code and timimg
-*******************************************************
-
-DWRead    clra                          ; clear Carry (no framing error)
-          deca                          ; clear Z flag, A = timeout msb ($ff)
-          tfr       cc,b
-          pshs      u,x,dp,b,a          ; preserve registers, push timeout msb
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-          tfr       a,dp                ; set direct page to $FFxx
-          ;setdp     $ff
           leau      ,x                  ; U = storage ptr
           ldx       #0                  ; initialize checksum
-          lda       #$01                ; A = serial in mask
-          bra       rx0030              ; go wait for start bit
 
-* Read a byte
-rxByte    leau      1,u                 ; bump storage ptr
-          leay      ,-y                 ; decrement request count
-          lda       <BBIN               ; read bit 0
-          lsra                          ; move bit 0 into Carry
-          ldd       #$ff20              ; A = timeout msb, B = shift counter
-          sta       ,s                  ; reset timeout msb for next byte
-          rorb                          ; rotate bit 0 into byte accumulator
-rx0010    lda       <BBIN               ; read bit (d1, d3, d5)
-          lsra
-          rorb
-          bita      1,s                 ; 5 cycle delay
-          bcs       rx0020              ; exit loop after reading bit 5
-          lda       <BBIN               ; read bit (d2, d4)
-          lsra
-          rorb
-          leau      ,u
-          bra       rx0010
+* initialise timeout
+rxNext    ldb       #$ff                ; init timeout LSB
+         stb       ,s                  ; init timeout MSB - don't need
+                                       ; this 1st time around.
 
-rx0020    lda       <BBIN               ; read bit 6
-          lsra
-          rorb
-          leay      ,y                  ; test request count
-          beq       rx0050              ; branch if final byte of request
-          lda       <BBIN               ; read bit 7
-          lsra
-          rorb                          ; byte is now complete
-          stb       -1,u                ; store received byte to memory
-          abx                           ; update checksum
-          lda       <BBIN               ; read stop bit
-          anda      #$01                ; mask out other bits
-          beq       rxExit              ; exit if framing error
+* character available?
+rxAvail          lda       UARTSTA2
+         bita      #1
+         bne       rxGet
 
-* Wait for a start bit or timeout
-rx0030    bita      <BBIN               ; check for start bit
-          beq       rxByte              ; branch if start bit detected
-          bita      <BBIN               ; again
-          beq       rxByte
-          ldb       #$ff                ; init timeout lsb
-rx0040    bita      <BBIN
-          beq       rxByte
+* no. Decrement timeout
           subb      #1                  ; decrement timeout lsb
-          bita      <BBIN
-          beq       rxByte
-          bcc       rx0040              ; loop until timeout lsb rolls under
-          bita      <BBIN
-          beq       rxByte
+          bcc       rxAvail             ; loop until timeout lsb rolls under
           addb      ,s                  ; B = timeout msb - 1
-          bita      <BBIN
-          beq       rxByte
+                                       ; leaves CC.C=0 on timeout
           stb       ,s                  ; store decremented timeout msb
-          bita      <BBIN
-          beq       rxByte
-          bcs       rx0030              ; loop if timeout hasn't expired
-          bra       rxExit              ; exit due to timeout
-
-rx0050    lda       <BBIN               ; read bit 7 of final byte
-          lsra
-          rorb                          ; byte is now complete
-          stb       -1,u                ; store received byte to memory
-          abx                           ; calculate final checksum
-          lda       <BBIN               ; read stop bit
-          anda      #$01                ; mask out other bits
-          ora       #$02                ; return SUCCESS if no framing error
-
-* Clean up, set status and return
-rxExit    leas      1,s                 ; remove timeout msb from stack
-          inca                          ; A = status to be returned in C and Z
+         bcc       rxTimout            ; oops!
+          ldb       #$ff                ; reload timeout LSB
+         bra       rxAvail             ; test again..
+
+* yes. Get it and move on
+rxGet    lda       UARTDAT2
+         abx                           ; accummulate checksum
+         sta       ,u+                 ; store byte
+         leay      ,-y                 ; decrement count
+         bne       rxNext
+         lda       #4                  ; represents CC.Z=1
+                                       ; to indicate all bytes rx'ed
+
+* clean up, set status and return
+rxExit   leas      1,s                 ; remove timeout MSB from stack
           ora       ,s                  ; place status information into the..
           sta       ,s                  ; ..C and Z bits of the preserved CC
           leay      ,x                  ; return checksum in Y
-          puls      cc,dp,x,u,pc        ; restore registers and return
-          ;setdp     $00
-
-          ENDC
-          ENDC
-          ENDC
+          puls      cc,x,u,pc          ; restore registers and return
 
+rxTimout  clra                         ; represents CC.C=0
+         bra       rxExit
index d262968..1b1d1d7 100644 (file)
@@ -1,12 +1,12 @@
 *******************************************************
 *
-* Copied from HDB-DOS from toolshed.sf.net
+* Derived from HDB-DOS from toolshed.sf.net
 * The original code is public domain
 *
 * DWWrite
 *    Send a packet to the DriveWire server.
 *    Serial data format:  1-8-N-1
-*    4/12/2009 by Darren Atkinson
+*    28Jul2106 by Neal Crook for Multicomp UART
 *
 * Entry:
 *    X  = starting address of data to send
 *    All others preserved
 *
 
-
-          IFNE ARDUINO
-DWWrite   pshs      a                  ; preserve registers
-txByte
-          lda       ,x+                ; get byte from buffer
-          sta       $FF52              ; put it to PIA
-loop@     tst       $FF53              ; check status register
-          bpl       loop@              ; until CB1 is set by Arduino, continue looping
-          tst       $FF52              ; clear CB1 in status register
-          leay      -1,y                ; decrement byte counter
-          bne       txByte              ; loop if more to send
-
-          puls      a,pc                ; restore registers and return
-
-          ELSE
-
-          IFNE JMCPBCK
-DWWrite   pshs      d,cc              ; preserve registers
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-txByte
-          lda       ,x+
-          sta       $FF44
-          leay      -1,y                ; decrement byte counter
-          bne       txByte              ; loop if more to send
-
-          puls      cc,d,pc           ; restore registers and return
-
-          ELSE
-          IFNE BECKER
-          IFNDEF BCKPORT
-BCKPORT   equ   $FF42
-          ENDC
-DWWrite   pshs      d,cc              ; preserve registers
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-;          ldu       #BBOUT              ; point U to bit banger out register
-;          lda       3,u                 ; read PIA 1-B control register
-;          anda      #$f7                ; clear sound enable bit
-;          sta       3,u                 ; disable sound output
-;          fcb       $8c                 ; skip next instruction
-
-txByte
-          lda       ,x+
-          sta       BCKPORT
-          leay      -1,y                ; decrement byte counter
-          bne       txByte              ; loop if more to send
-
-          puls      cc,d,pc           ; restore registers and return
-          ENDC
-          ENDC
-          ENDC
-
-          IFEQ BECKER+JMCPBCK+ARDUINO
-          IFNE BAUD38400
 *******************************************************
-* 38400 bps using 6809 code and timimg
+* 57600 (115200) bps using 6809 code and hw UART
 *******************************************************
 
-DWWrite   pshs      u,d,cc              ; preserve registers
+DWWrite   pshs      cc,a                               ; preserve registers
           IFEQ      NOINTMASK
           orcc      #IntMasks           ; mask interrupts
           ENDC
-          ldu       #BBOUT              ; point U to bit banger out register
-          lda       3,u                 ; read PIA 1-B control register
-          anda      #$f7                ; clear sound enable bit
-          sta       3,u                 ; disable sound output
-          fcb       $8c                 ; skip next instruction
-
-txByte    stb       ,--u                ; send stop bit
-          leau      ,u+
-          lda       #8                  ; counter for start bit and 7 data bits
-          ldb       ,x+                 ; get a byte to transmit
-          lslb                          ; left rotate the byte two positions..
-          rolb                          ; ..placing a zero (start bit) in bit 1
-tx0010    stb       ,u++                ; send bit
-          tst       ,--u
-          rorb                          ; move next bit into position
-          deca                          ; decrement loop counter
-          bne       tx0010              ; loop until 7th data bit has been sent
-          leau      ,u
-          stb       ,u                  ; send bit 7
-          lda       ,u++
-          ldb       #$02                ; value for stop bit (MARK)
-          leay      -1,y                ; decrement byte counter
-          bne       txByte              ; loop if more to send
 
-          stb       ,--u                ; leave bit banger output at MARK
-          puls      cc,d,u,pc           ; restore registers and return
+WrBiz     lda          UARTSTA2
+          bita         #2
+          beq          WrBiz                           ; busy
 
-          ELSE
+          lda          ,x+                                     ; get byte to transmit
+          sta          UARTDAT2                        ; send byte
 
-          IFNE H6309
-*******************************************************
-* 57600 (115200) bps using 6309 native mode
-*******************************************************
-
-DWWrite   pshs      u,d,cc              ; preserve registers
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-*         ldmd      #1                  ; requires 6309 native mode
-          ldu       #BBOUT+1            ; point U to bit banger out register +1
-          aim       #$f7,2,u            ; disable sound output
-          lda       #8                  ; counter for start bit and 7 data bits
-          fcb       $8c                 ; skip next instruction
-
-txByte    stb       -1,u                ; send stop bit
-tx0010    ldb       ,x+                 ; get a byte to transmit
-          lslb                          ; left rotate the byte two positions..
-          rolb                          ; ..placing a zero (start bit) in bit 1
-          bra       tx0030
-
-tx0020    bita      #1                  ; even or odd bit number ?
-          beq       tx0040              ; branch if even (15 cycles)
-tx0030    nop                           ; extra (16th) cycle
-tx0040    stb       -1,u                ; send bit
-          rorb                          ; move next bit into position
-          deca                          ; decrement loop counter
-          bne       tx0020              ; loop until 7th data bit has been sent
-          leau      ,u+
-          stb       -1,u                ; send bit 7
-          ldd       #$0802              ; A = loop counter, B = MARK value
-          leay      -1,y                ; decrement byte counter
-          bne       txByte              ; loop if more to send
-
-          stb       -1,u                ; final stop bit
-          puls      cc,d,u,pc           ; restore registers and return
-
-          ELSE
-*******************************************************
-* 57600 (115200) bps using 6809 code and timimg
-*******************************************************
-
-DWWrite   pshs      dp,d,cc             ; preserve registers
-          IFEQ      NOINTMASK
-          orcc      #IntMasks           ; mask interrupts
-          ENDC
-          ldd       #$04ff              ; A = loop counter, B = $ff
-          tfr       b,dp                ; set direct page to $FFxx
-          ;setdp     $ff
-          ldb       <$ff23              ; read PIA 1-B control register
-          andb      #$f7                ; clear sound enable bit
-          stb       <$ff23              ; disable sound output
-          fcb       $8c                 ; skip next instruction
-
-txByte    stb       <BBOUT              ; send stop bit
-          ldb       ,x+                 ; get a byte to transmit
-          nop
-          lslb                          ; left rotate the byte two positions..
-          rolb                          ; ..placing a zero (start bit) in bit 1
-tx0020    stb       <BBOUT              ; send bit (start bit, d1, d3, d5)
-          rorb                          ; move next bit into position
-          exg       a,a
-          nop
-          stb       <BBOUT              ; send bit (d0, d2, d4, d6)
-          rorb                          ; move next bit into position
-          leau      ,u
-          deca                          ; decrement loop counter
-          bne       tx0020              ; loop until 7th data bit has been sent
-
-          stb       <BBOUT              ; send bit 7
-          ldd       #$0402              ; A = loop counter, B = MARK value
-          leay      ,-y                 ; decrement byte counter
-          bne       txByte              ; loop if more to send
-
-          stb       <BBOUT              ; leave bit banger output at MARK
-          puls      cc,d,dp,pc          ; restore registers and return
-          ;setdp     $00
-
-          ENDC
-          ENDC
-          ENDC
+          leay         ,-y                 ; decrement byte counter
+          bne          WrBiz                           ; loop if more to send
 
+          puls         cc,a,pc                         ; restore registers and return