How to read bits from tape

Basic and Machine Language

Moderator: Moderators

nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: How to read bits from tape

Post by nippur72 »

I got it! :D

Thanks to this post and this github repo by @pixel I got a better understanding.

Basically you program the VIA chip to trigger an interrupt when the cassette bit changes; the VIA counter contains the length of the received pulse.

I finally wrote the monitor program I wanted to write back in 2006. It's published here. It changes 36878 and 36879 when a pulse is received.

The monitor will be very useful as I'm playing with a FPGA (Mistica board) and want to implement real tape loading in the existing VIC-20 implementation. I need it as a debug tool.

Code: Select all

   processor 6502

   include <macros.lm>
   include <macros_16.lm>

   include <vic20.lm>
   
   org BASIC_RAM

   basic start
      10 sys {tapemon}
   basic end

dim tape_old_irq as word

const IRQ = $314
const VIA2_COUNTER = $9124
const VIA2_ACR     = $912b
const VIA2_PCR     = $912e

const TIMER_VALUE = $ffff

const COLOR1 = 3*16+3+8
const COLOR2 = 1*16+1+8

sub tapemon()

   ; not sure: disable all interrupts
   sei
   lda #$7f
   sta $911e  ; VIA 1 Interrupt Enable Register
   sta $912e  ; VIA 2 Interrupt Enable Register
   sta $912d  ; VIA 1 Interrupt Flag Register

   ; Start tape motor
   lda $911c
   and #$fd
   sta $911c

   ; Set IRQ vector
   ld16 tape_old_irq, IRQ
   ld16 IRQ, #bit_received

   ; Initialise VIA2 Timer 1 (cassette tape read)
   ld16 VIA2_COUNTER, TIMER_VALUE   ; Restart timer
   ld VIA2_ACR, #%00000000          ; One-shot mode
   ld VIA2_PCR, #%10000010          ; CA1 IRQ enable (tape pulse)

   ; Let the IRQ handler do everything
   cli
   clc   
   do : loop while not carry

; this routine gets triggered when the edge of the tape bit 
; is detected or when the timer counter underflows

bit_received:
   
   ; an actual bit decoding routine should look at underflow bit
   ; lda $912d       ; Get timer underflow bit.
   ; asl             ; Move underflow bit into carry.
   ; asl             ;
   ; it should also look into the counter value?

   ; color effect   
   lda $900f
   if a=#COLOR1 then 
      ld a, #COLOR2
   else
      ld a, #COLOR1
   end if
   sta $900f
       
   ; sound effect
   lda 36878
   if a=#15 then 
      ld a, #0
   else
      ld a, #15
   end if
   sta 36878

   ld16 VIA2_COUNTER, TIMER_VALUE        ; Restart timer.

   ; not sure: prepare for re-trigger?
   lda #$7f
   sta $912d

   ; complete the interrupt routine
   jmp $eb18

end sub
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: How to read bits from tape

Post by nippur72 »

ops wrote:I have disassembled Anirog fast loader, see https://github.com/ops/anirog-copy
Interesting, it doesn't seem to use IRQ at all...
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: How to read bits from tape

Post by nippur72 »

I have a new simpler version based on the Anirog loader, but still not easy to understand :(

Code: Select all

   sei
   lda #$27
   sta $9128
   ldx #$01

loop:
   lda #$02
   do
      bit     $912D
   loop while zero

   ; ???
   lda $912D
   stx $9129
   bit $9121   
   asl     
   asl     
   asl     

   ; color effect   
   lda $900f
   if a=#COLOR1 then 
      ld a, #COLOR2
   else
      ld a, #COLOR1
   end if
   sta $900f

   ; sound effect
   lda 36878
   if a=#15 then 
      ld a, #0
   else
      ld a, #15
   end if
   sta 36878
   
   jmp loop
Forbidden64
Vic 20 Hobbyist
Posts: 146
Joined: Sun Feb 28, 2016 9:59 pm
Location: CA USA

Re: How to read bits from tape

Post by Forbidden64 »

nippur72 wrote:@Forbidden64, was him Luigi Di Fraia ?

Ya, that is the guy. Somewhere, i can't find it, he did a complete analysis of Rabbit's fast loader for the VIC-20.

Interestingly though, the 6522 seems to allow for automatic control of all this stuff. They just didn't use it likely because Chuck Peddle had hand tuned the original datasette operation with an oscilloscope and tuned it in software. He later said that he got burned out on programming from doing that project.

Since Chuck was gone, they had to do a reverse engineer to mirror a compatible version of what he had done. So my understanding is they tried successfully to reproduce what he had done in software. That said, the VIA is highly capable and doesn't necessarily require bit banging. The 6526 does though on the c64 because from my understanding, the shift register doesn't work internally. I'm sure eslapion would know better than I on that portion.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: How to read bits from tape

Post by nippur72 »

one more question: the cassette write bit is on port B of the secondo VIA (bit 3) which is also shared with keyboard column read ... how can I separate the two cases, e.g. how can I tell I am "saving" and thus the bit 3 is meaningful vs I am not "saving" and I am scanning the keyboard.

I see that during save the keyboard doesn't affect this bit.... how this is done?
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How to read bits from tape

Post by Mike »

During KERNAL tape operations, the IRQ is re-vectored and doesn't anymore scan the keyboard - except for the STOP key.
User avatar
highinfidelity
Vic 20 Nerd
Posts: 644
Joined: Thu Jul 28, 2011 2:34 am
Website: http://www.hirtel.it
Location: Torino, Italy.

Re: How to read bits from tape

Post by highinfidelity »

Now that the issue has been settled - I don't even understand if this is somehow related, but I remember that on the VIC20 manual, among the last "technical" pages, there was a sample program that was supposed to read data from tape by "buffering" them. The text pretended that the tape would stop-and-go intermittently, which should have been a clear demonstration that the VIC was actually "buffering" from the Datassette. I was very curious to see that happening, but the program was either incomplete or was supposed to be used in an environment about which I had no knowledge, and I could never actually see that "buffering" stop-and-go. Did anyone else tried or remember what I'm talking about?
Last edited by highinfidelity on Tue Apr 30, 2019 1:31 am, edited 2 times in total.
GOD is REAL. Unless declared DOUBLE PRECISION.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How to read bits from tape

Post by Mike »

The examples in the User's Guide for storing/retrieving tape data files work fine as is.

The tape buffer takes 192 bytes and is only written when full or when the file is closed. Likewise, on read first the buffer is filled (upon the first GET# or INPUT# on an empty buffer) and then the tape is stopped until a GET# or INPUT# has consumed all the data in the tape buffer - which then starts the motor again, reads the next data block from tape, and once again stops the motor.

Note those data files can only be read back by an OPEN, GET#/INPUT#, CLOSE sequence (or the equivalent KERNAL calls OPEN, CHKIN, CHRIN/GETIN, CLRCHN, CLOSE). They're not compatible with the KERNAL LOAD routine.

With KERNAL SAVE/LOAD on tape no buffering takes place, the bytes are directly written in a single block from memory to tape or read from tape to memory (... O.K., there's also the second copy of the header and payload being stored, and used for error checking on LOAD/VERIFY but I just mention this in passing ...).
Post Reply