#include <device.h>
#include <devlpr.h>
-/* random test places */
-uint8_t *lpstat = (uint8_t *)0xFF00;
-uint8_t *lpdata = (uint8_t *)0xFF01;
+volatile uint8_t * const pia0b = (uint8_t *)0xFF02;
+volatile uint8_t * const pia1a = (uint8_t *)0xFF20;
+volatile uint8_t * const pia1b = (uint8_t *)0xFF22;
int lpr_open(uint8_t minor, uint16_t flag)
{
- minor;
- flag; // shut up compiler
- return 0;
+ if (minor < 2)
+ return 0;
+ udata.u_error = ENODEV;
+ return -1;
}
int lpr_close(uint8_t minor)
{
- minor; // shut up compiler
+ if (minor == 1)
+ dw_lpr_close();
return 0;
}
-int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+static int iopoll(int sofar)
{
- int c = udata.u_count;
- char *p = udata.u_base;
- uint16_t ct;
-
- minor;
- rawflag;
- flag; // shut up compiler
+ /* Ought to be a core helper for this lot ? */
+ if (need_resched())
+ _sched_yield();
+ if (udata.u_cursig || udata.u_ptab->p_pending) {
+ if (sofar)
+ return sofar;
+ udata.u_error = EINTR;
+ return -1;
+ }
+ return 0;
+}
- while (c-- > 0) {
- ct = 0;
+int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+ uint8_t *p = udata.u_base;
+ uint8_t *pe = p + udata.u_count;
+ int n;
+ irqflags_t irq;
- /* Try and balance polling and sleeping */
- while (*lpstat & 2) {
- ct++;
- if (ct == 10000) {
- udata.u_ptab->p_timeout = 3;
- if (psleep_flags(NULL, flag)) {
- if (udata.u_count)
- udata.u_error = 0;
- return udata.u_count;
- }
- ct = 0;
+ if (minor == 1) {
+ while (p < pe) {
+ if ((n = iopoll(pe - p)) != 0)
+ return n;
+ dw_lpr(ugetc(p++));
+ }
+ } else {
+ while (p < pe) {
+ /* Printer busy ? */
+ while (*pia1b & 1) {
+ if ((n = iopoll(pe - p)) != 0)
+ return n;
}
+ /* The Dragon shares the printer and keyboard scan
+ lines. Make sure we don't collide */
+ irq = di();
+ *pia0b = ugetc(p++);
+ *pia1a |= 0x02; /* Strobe */
+ *pia1a &= ~0x02;
+ irqrestore(irq);
}
- /* Data */
- *lpdata = ugetc(p++);
}
- return udata.u_count;
+ return pe - p;
}
#ifndef __DEVLPR_DOT_H__
#define __DEVLPR_DOT_H__
-int lpr_open(uint8_t minor, uint16_t flag);
-int lpr_close(uint8_t minor);
-int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+extern int lpr_open(uint8_t minor, uint16_t flag);
+extern int lpr_close(uint8_t minor);
+extern int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+
+extern void dw_lpr(uint8_t c);
+extern void dw_lpr_close(void);
#endif
.globl _dw_operation
.globl _dw_reset
+ .globl _dw_lpr
+ .globl _dw_lpr_close
+ .globl _dw_rtc_read
+
+
; imported
.globl map_process_a
.globl map_kernel
ReadErr comb ; set carry bit
ReadEx puls d,x,y,pc
+ .area .text
+;
+; Virtual devices on DriveWire
+;
+; Line printer
+; RTC
+; Virtual serial ???
+;
+;
+; dw_lpr(uint8_t c)
+;
+; Print a byte to drive wire printers
+;
+; B holds the byte. Call with interrupts off
+;
+_dw_lpr:
+ pshs y
+ stb lprb2
+ ldx #lprb
+ ldy #2
+dwop:
+ jsr DWWrite
+ puls y,pc
+
+;
+; dw_lpr_close(void)
+;
+; Close the printer device
+;
+_dw_lpr_close:
+ pshs y
+ ldx #lprb3
+ ldy #1
+ bra dwop
+
+;
+; uint8_t dw_rtc_read(uint8_t *p)
+;
+_dw_rtc_read:
+ pshs y
+ ldy #2
+ pshs x
+ ldx #lprrtw
+ jsr DWWrite
+ puls x
+ ldy #6
+ clra
+ jsr DWRead
+ clrb
+ sbcb #0
+ bra dwop
+
+ .area .data
+
+lprb: .db 0x50 ; print char
+lprb2: .db 0x00 ; filled in with byte to send
+lprb3: .db 0x46 ; printer flush
+lprrtw: .db 0x23 ; request for time
+
+ .area .common
+
+
; Used by DWRead and DWWrite
IntMasks equ $50
NOINTMASK equ 1