From: Alan Cox Date: Mon, 1 Jun 2015 19:47:21 +0000 (+0100) Subject: trs80: first cut at drivewire support X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=361648dc88d79c7cb6769902d7e6dad85475e17e;p=FUZIX.git trs80: first cut at drivewire support Limited to a whopping 19200 baud, and assumes you set up the /dev/tty3 port as you want then run drivewire (don't mix and match!) Needs optimising, actually testing once I've fixed the emulator to do better serial proxying. --- diff --git a/Kernel/platform-trs80/Makefile b/Kernel/platform-trs80/Makefile index 82c1e02f..c3ce2e82 100644 --- a/Kernel/platform-trs80/Makefile +++ b/Kernel/platform-trs80/Makefile @@ -4,12 +4,17 @@ CSRCS += devices.c main.c DISCARD_CSRCS = discard.c devhd_discard.c ASRCS = trs80.s crt0.s -ASRCS += tricks.s commonmem.s floppy.s +ASRCS += tricks.s commonmem.s floppy.s drivewire.s + +DSRCS = ../dev/devdw.c COBJS = $(CSRCS:.c=.rel) AOBJS = $(ASRCS:.s=.rel) DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel) -OBJS = $(COBJS) $(AOBJS) $(DISCARD_COBJS) +DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS)) +OBJS = $(COBJS) $(AOBJS) $(DISCARD_COBJS) $(DOBJS) + +CROSS_CCOPTS += -I../dev/ JUNK = $(CSRCS:.c=.lst) $(CSRCS:.c=.asm) $(CSRCS:.c=.sym) $(ASRCS:.s=.lst) $(ASRCS:.s=.sym) $(CSRCS:.c=.rst) $(ASRCS:.s=.rst) @@ -21,6 +26,9 @@ $(COBJS): %.rel: %.c $(AOBJS): %.rel: %.s $(CROSS_AS) $(ASOPTS) $< +$(DOBJS): %.rel: ../dev/%.c + $(CROSS_CC) $(CROSS_CCOPTS) -c $< + $(DISCARD_COBJS): %.rel: %.c $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< diff --git a/Kernel/platform-trs80/devices.c b/Kernel/platform-trs80/devices.c index ad1b01fa..1b804020 100644 --- a/Kernel/platform-trs80/devices.c +++ b/Kernel/platform-trs80/devices.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,11 @@ struct devsw dev_tab[] = /* The device driver switch table */ /* 4: /dev/mem etc System devices (one offs) */ { no_open, no_close, sys_read, sys_write, sys_ioctl }, /* Pack to 7 with nxio if adding private devices and start at 8 */ + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 8: /dev/dw DriveWire remote disk images */ + { dw_open, no_close, dw_read, dw_write, no_ioctl }, }; bool validdev(uint16_t dev) diff --git a/Kernel/platform-trs80/drivewire.s b/Kernel/platform-trs80/drivewire.s new file mode 100644 index 00000000..c84b3278 --- /dev/null +++ b/Kernel/platform-trs80/drivewire.s @@ -0,0 +1,153 @@ + .module drivewire + + .globl _dw_operation + .globl _dw_reset + + .globl map_process_a + .globl map_kernel + + + + .area _COMMONMEM + + ; dw_reset(driveptr) +_dw_reset: + ret + + ; dw_operation(cmdblock, driveptr) +_dw_operation: + pop bc ; return + pop iy ; cmdblock + pop de ; driveptr + push de + push iy + push bc + + ld b, 5(iy) ; page map + call map_process_a + ld h, 3(iy) ; pointer + ld l, 4(iy) + ld b, 1(iy) + ld c, 2(iy) + xor a + cp (iy) + ld a, (de) + jr nz, is_write + call dw_read_sector +dw_op_ret: + ld hl, #0 + jr nc, dw_op_ok + dec hl +dw_op_ok: + jp map_kernel +is_write: + call dw_write_sector + jr dw_op_ret + +; Entry A = command +; Exit BCD = 0 + +dw_hdr: + call txbyte + ld a, (de) ; drive + call txbyte + xor a ; LSN 23-16 = 0 + call txbyte + ld a, b ; sector high + call txbyte + ld a, c ; sector low + call txbyte + ld b, #0 + ld d, b ;checkum starts 0 + ld e, b + ret + +dw_write_sector: + ld a, #0x57 ; WRITE + call dw_hdr +payload1: + ld a, e + add (hl) + ld e, a + ld a, d + adc #0 + ld d, a + ld a, (hl) + inc hl + call txbyte + djnz payload1 + ld a, d + call txbyte + ld a, e + call txbyte + call rxbyte + ret + +dw_read_sector: + ld a, #0xD2 ; READEX + call dw_hdr + call rxbyte + ret c + or a + jr nz, error_ret +; +; 256 receive bytes +; +payload2: + call rxbyte + ret c + ld (hl), a + inc hl + ld a, (hl) + add e + ld e, a + ld a, #0 + add d + ld d, a + djnz payload2 + ld a, d + call txbyte + ld a, e + call txbyte + call rxbyte + ret c + or a + ret z + ; We could be smarter about error codes and reporting ? +error_ret: + scf + ret + +; +; Serial logic, polled interrupts off so we can do a reliable 19200 +; baud (hardware limit) +; +txbyte: + in a, (0xEA) + bit 6, a + jr z, txbyte + out (0xEB), a + ret +; +; We poll for receive in this mode as interrupts are off and we want +; *speed* +; +rxbyte: + ; Loop time is 56 clocks so ~=72K loops/second + ; we want to spin for 0.25 (Drivewire limit) + ld bc, #0x46 +rxbytel: + in a, (0xEA) ; 11 + bit 7, a ; 8 + jr nz, gotbyte ; 7(12) + dec bc ; 10 + ld a, b ; 4 + or c ; 4 + jr nz, rxbytel ; 7(12) + scf + ret +gotbyte: + in a, (0xEB) + or a + ret + diff --git a/Kernel/platform-trs80/fuzix.lnk b/Kernel/platform-trs80/fuzix.lnk index 210e6910..da04512a 100644 --- a/Kernel/platform-trs80/fuzix.lnk +++ b/Kernel/platform-trs80/fuzix.lnk @@ -40,4 +40,6 @@ devsys.rel platform-trs80/devlpr.rel platform-trs80/devtty.rel platform-trs80/discard.rel +platform-trs80/devdw.rel +platform-trs80/drivewire.rel -e