Mercurial > hg > Members > kono > nitros9-code
changeset 2574:236dd2507569
Added DW4 code from Darren A.
author | boisy |
---|---|
date | Sun, 15 May 2011 18:14:26 +0000 |
parents | 51b6d97bfc7e |
children | a9a5be5114b2 |
files | level1/modules/dw4read.asm level1/modules/dw4write.asm |
diffstat | 2 files changed, 205 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level1/modules/dw4read.asm Sun May 15 18:14:26 2011 +0000 @@ -0,0 +1,140 @@ +******************************************************* +* +* DWRead - 6809 Turbo Edition 115k / 230k +* Receive a response from the DriveWire server. +* Times out if no data received within 1.3 (0.66) seconds. +* +* THIS VERSION REQUIRES ONE OR MORE SYNC BYTES +* WHERE THE THE FINAL SYNC BYTE IS $C0 AND ANY +* PRECEDING SYNC BYTES ARE $FF. +* +* THE DATA BYTES MUST BE TRANSMITTED IN REVERSE +* BIT ORDER (MOST-SIGNIFICANT FIRST). +* +* Serial data format: 8-N-2 (TWO STOP BITS MANDATORY) +* +* Entry: +* X = storage address for incoming data +* Y = number of bytes required +* +* Exit: +* CC = Z set on success, cleared on timeout +* Y = checksum +* U is preserved +* All others clobbered +* +*BBIN equ $FF22 ; bit banger input port + SETDP $FF +DWRead pshs y,x,dp,a,cc ; save registers (A allocates space for status) + orcc #$50 ; mask interrupts + lda #$FF ; select hardware page.. + tfr a,dp ; ..as the direct page + ldx #0 ; initialize timeout counter + stx <$FF92 ; disable GIME interrupts + ldd <$FF92 ; clear spurious interrupts + +* Turn off PIA interrupt sources except for the bit banger's CD input pin. +* Also enable sound output from the DAC to stabilize the single-bit sound line. + lda <$FF01 ; save PIA 0 controls on the stack + ldb <$FF03 + pshs d + anda #$F6 ; clear IRQ enables and audio mux selects + andb #$F6 + sta <$FF01 ; set new control state for PIA 0 + stb <$FF03 + lda <$FF00 ; ensure the IRQ outputs are cleared + ldb <$FF02 + lda <$FF21 ; save PIA 1 controls on the stack + ldb <$FF23 + pshs d,cc ; CC allocates space for byte adjustment value + anda #$FC ; clear FIRQ enables and sound enable + andb #$F6 + addd #$0108 ; set CD FIRQ enable and sound enable + sta <$FF21 ; set new control state for PIA 1 + stb <$FF23 + +* Setup byte adjustment value + ldd #$01FE ; ACCA = serial in mask; ACCB = byte adjust mask + andb <BBIN ; ACCB = byte adjust value + stb ,s ; save in pre-allocated stack space + +* Wait for Sync Byte(s) or Timeout +sync1 ldb #2 ; set counter to wait for 2 low samples +sync2 bita <BBIN ; sample input + beq sync3 ; branch if low + leax ,-x ; decrement timeout counter + bne sync1 ; loop if timeout has not expired + bra rxDone ; exit due to timeout +sync3 lsrb ; have there been 2 consecutive low samples? + bcc sync2 ; keep waiting if no + ldx 8,s ; point X to storage buffer and.. + leax -1,x ; ..adjust for pre-increment +sync4 bita <BBIN ; sample input + bne rxStart ; branch if input has returned hi + rorb ; bump secondary timeout counter + bcc sync4 ; branch if not timeout + bra rxDone ; exit due to timeout +rxStart lda <$FF20 ; reset FIRQ + sync ; wait for the first byte's start bit + jmp <rxFirst,pcr ; 4-cycle equivalent of: bra rxFirst + +* Byte receiver loop +rxNext sync ; wait for start bit + sta ,x ; store previous data byte +rxFirst lda <BBIN ; bit 0 + asla + nop + adda <BBIN ; bit 1 + asla + adda >BBIN ; bit 2 + asla + nop + adda <BBIN ; bit 3 + asla + clrb ; ACCB = 0 + adda <BBIN ; bit 4 + asla + incb ; ACCB = 1 + adda <BBIN ; bit 5 + asla + adda >BBIN ; bit 6 + asla + abx ; increment storage ptr + adda <BBIN ; bit 7 + adda ,s ; adjust byte value + bita <$FF20 ; reset FIRQ + leay -1,y ; decrement counter + bne rxNext ; loop if more bytes to read + sta ,x ; store final byte + clra ; status = SUCCESS +rxDone sta 6,s ; store status on stack + leas 1,s ; pop byte adjustment value + +* Restore previous PIA control settings + puls d ; restore original PIA 1 controls + sta <$FF21 + stb <$FF23 + puls d ; restore original PIA 0 controls + sta <$FF01 + stb <$FF03 + lda <$FF20 ; make sure the CD FIRQ has been cleared + + IF NITROS +* Restoration of GIME interrupts in NitrOS9 + ldd >D.IRQER ; retrieve shadow copy of IRQ/FIRQ enable regs + std <$FF92 ; restore GIME + ldd <$FF92 ; clear spurious interrupts + ENDIF + +* Checksum computation + clrb ; initialize checksum LSB + puls cc,a,dp,x,y ; restore IRQ masks, DP and the caller params + tsta ; timeout error? + bne rxExit ; branch if yes +sumLoop addb ,x+ ; get one byte and add to.. + adca #0 ; ..the 16-bit checksum in ACCD + leay -1,y ; decrement counter + bne sumLoop ; loop until all data summed + andcc #$FE ; clear carry (no framing error) +rxExit tfr d,y ; move checksum into Y without affecting CC.Z + rts ; return
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level1/modules/dw4write.asm Sun May 15 18:14:26 2011 +0000 @@ -0,0 +1,65 @@ +******************************************************* +* +* DW4Write - 6809 Turbo Edition 115k / 230k +* Send a packet to the DriveWire server. +* Serial data format: 8-N-2 +* +* Entry: +* X = address of the data to be sent +* Y = number of bytes to send +* +* Exit: +* X = address of last byte sent + 1 +* Y = 0 +* All others preserved +* +*BBOUT equ $FF20 ; bit banger output port + +DWWrite pshs u,d,cc ; preserve registers + orcc #$50 ; mask interrupts + ldu #BBOUT ; point U to output port + lda 3,u ; read PIA 1-B control register + anda #$F7 ; clear sound enable bit + sta 3,u ; disable sound output + +* Wait for serial input line to become idle +wait1 lda 2,u ; sample input + ldb #$80 ; setup ACCB as a shift counter +wait2 eora 2,u ; look for changing input + lsra ; shift 'changed' bit into Carry + lda 2,u ; sample input + rorb ; rotate 'changed' bit into ACCB + bcc wait2 ; loop for 8 samples + bne wait1 ; try again if changes seen in the input + +* Byte transmitter loop + ldb #2 + lda ,x ; retrieve first byte from buffer +txByte decb ; ACCB = 1 (start bit / byte incrementor) + abx ; increment data ptr + stb ,u ; send start bit + asla ; move bit 0 into position + nop + sta ,u ; bit 0 + rora + sta ,u+ ; bit 1 + lsra + sta -1,u ; bit 2 + lsra + sta ,-u ; bit 3 + lsra + incb ; ACCB = 2 (stop bit) + sta ,u ; bit 4 + lsra + sta ,u+ ; bit 5 + lsra + sta -1,u ; bit 6 + lsra + sta ,-u ; bit 7 + lda ,x ; fetch next byte + stb ,u ; send stop bit + leay -1,y ; decrement counter + bne txByte ; loop if more bytes to send + + puls cc,d,u,pc ; restore registers and return +