0 Members and 1 Guest are viewing this topic.
The CIA#1 timer A is used to generate the IRQs.
;interruptPHALDA $DC0D ;CIA interrupt status (clear IRQ)+ serial-byte-readyORA c3po ;prior byte-readyAND #8 ;check byte-readySTA c3po ;save statusBEQ audio ;no byte readyLDA #$10 ;CLK output bitEOR $DD00 ;toggle serial lineSTA $DD00 ; (request next byte)audio:...LDA $DC0C ;read old byte from fast-serial bus...
;repeat the following 4 times to get 4 bit-pairs (8 bits total)LDA $DD00 ;4 cyclesLSR ;2 cyclesLSR ;2 cyclesNOP ;2 cycles;subtotal = 10*4 = 40 cycles;save byte, synchronize, and loop ~ 24 cycles;grand total = 64 microseconds
STX $400C ;4 cycles -- send data on fast serial busLDA flipper ;0 cycles (occurs during transmit)EOR #CLK ;0STA flipper ;0LDA #8 ;0 cycles -- test fast serial completewaitBIT $400D ;64*2 cycles -- wait serial byte transmittedBNE wait ;3 cyclesRTS ;6 cycles#### ;~12 cycles -- read next byte and loop controlJSR transfer ;6 cyclestransferLDA bus ;4 cyclesCMP bus ;4 cyclesBNE transfer ;2 cycles (assume no loop -- stable)AND flipper ;3 cyclesBEQ transfer ;2 cycles (assume no loop -- handshake received);total 174 cycles = 87 microseconds
BDD, is there some specific bug that C128 programmers should be aware of? I've heard about the TOD/Alarm bug... but you have something else in mind?
Considering your work on [your] dual port serial adapter, I thought you might have some suggestions / preferences to using IRQ versus NMI. As I understand your adapter runs about 38k (bits)which is about 4.75k byte/s...
...and comparable to the 7.8kHz (bytes/s) interrupt rate I'm using. So maybe you know some effecient techniques for managing that data flow ? I also understand it uses an ACIA not a CIA, but I would think there's some similarities in programming...
*Conclusion*Now videos are playing very well on my SD2IEC device. Not so well on C1581 because of stupid Commodore and/or JiffyDOS ROMs. I wonder how a CMD-HD would hold out? Anyway, one way to fix the problem is to burn a custom ROM without stupidity built into the transfer routines. I'm still open to other options...
;CPU interrupt - 7 cyclesPHA ;3 cyclesTXA ;3 cyclesPHA ;3 cyclesTYA ;3 cyclesPHA ;3 cyclesLDA $FF00 ;4 cyclesPHA ;3 cyclesLDA #0 ;2 cyclesSTA $FF00 ;4 cycles;test for BRK or real IRQTSX ;2 cyclesLDA $105,X ;4 cyclesAND #$10 ;2 cyclesBEQ doIRQ ;3 cyclesdoIRQ:JMP ($314) ;5 cycles
PLA ;4 cyclesSTA $FF00 ;4 cyclesPLA ;4 cyclesTAY ;2 cyclesPLA ;4 cyclesTAX ;2 cyclesPLA ;4 cyclesRTI ;6 cycles
;CPU interrupt - 7 cyclesPHA ;3 cycles; interrupt routine herePLA ;4 cyclesRTI ;6 cycles
getA:LDA $e000 ;4 cycles... ;process audioINC getA+1 ;6 cyclesBNE serial ;3 cycles;page wrap, 15 or 16 cyclesLDA getA+2CMP # >buffer_limit -1BCC setAhLDA # >buffer_start -2setAh:ADC #1STA getA+2serial:...
;A has data from serial buswrtS:STA memory ;4 cyclesINC wrtS+1 ;6 cyclesBNE exit ;3 cyclesINC wrtS+2 ;6 cyclesexit:
LDA c3po ;old byte-ready statusORA $DC0D ;clear IRQ and merge new byte-ready statusSTA c3po ;save current byte-ready status
BIT $DD0D ;clear NMILDA $DC0D ;get current byte-ready status
LDA countL ;3|4 cycles (2|3 bytes)BNE noWrap ;2|3 cycles (2 bytes)DEC countH ;5|6 cycles (2|3 bytes)noWrap:DEC countL ;5|6 cycles (2|3 bytes)
INC countL ;5|6 cycles (2|3 bytes)BNE noWrap ;2|3 cycles (2 bytes)INC countH ;5|6 cycles (2|3 bytes)noWrap:
SEC ;2 cycles (1 byte) -- may sometimes be omittedLDA #0 ;2 cycles (2 bytes)SBC countL ;3|4 cycles (2|3 bytes)STA countL ;3|4 cycles (2|3 bytes)LDA #0 ;2 cycles (2 bytes)SBC countH ;3|4 cycles (2|3 bytes)STA countH ;3|4 cycles (2|3 bytes)
DEC countL ;5|6 cycles (2|3 bytes)BNE noWrap ;2|3 cycles (2 bytes)DEC countH ;5|6 cycles (2|3 bytes)noWrap:
LDA countL ;3|4 cycles (2|3 bytes)BEQ no_mangle; 2|3 cycles (2 bytes)INC countH ;5|6 cycles (2|3 bytes)no_mangle:
LDA $DC0C ;get data byte;the next pair of DEC/BEQs take 14 cycles in the usual caseDEC packet_size_lowBEQ packet_wrapDEC sector_remainderBEQ get_status_byteSTA memory
LDA $DC0C ;get data byte;the following DEC/BEQ takes 7 cycles in the usual caseDEC normal_countBEQ exceptionSTA memory
LDA $DC0CDEC sector_remainderBEQ status_byteSTA memory
LDA $DC0CSTA memoryDEC sector_remainderBEQ status_byte
So I'm thinking with anti-C1581 drive to cancel out the normal C1581...