Main file   : speed1581.s
Current file: speed1581.s

0000r              ;    Speed-Loader für 1581 & C64
0000r              ;
0000r              ; ******** Labels 1581 ***********
0000r 
0000r                        buffer    := $0300
0000r                        bytesect   =   $ff
0000r                        c64off     = utilend-c64+2
0000r                        cache     := $0c00
0000r                        channel   :=   $50
0000r                        chnopn    := $9027
0000r                        chntab    :=   $bb
0000r                        data      := $023b
0000r                        delay     := $ad30
0000r                        dirflg    := $026e
0000r                        drivenr   :=   $ef
0000r                        eoi        =   $80
0000r                        error      =   $01
0000r                        getbuffp  := $9442
0000r                        getbyte   := $909b
0000r                        getdir    := $8f03
0000r                        hostflg   :=   $76
0000r                        jallocbf  := $ff66
0000r                        jbootrtn  := $ff5a
0000r                        jdejavu   := $ff60
0000r                        jerror    := $ff2d
0000r                        jjidle    := $aed9
0000r                        jobnr      =   $06
0000r                        job       := jobnr+2
0000r                        okmess    := $a862
0000r                        pointer   :=   $64
0000r                        quantity  :=   $54
0000r                        read       =   $80
0000r                        secadr    :=   $52
0000r                        sector    := jobnr*2+12
0000r                        side      :=   $96
0000r                        srchcmd   := $01db
0000r                        status    := $0234
0000r                        talk      := $ad5c
0000r                        temp      :=   $45
0000r                        tlkcode   := $ad6a
0000r                        tlkbroff   = $adf0-tlkcode
0000r                        tlklen     = $ae34-tlkcode
0000r                        tlkvect   := $01b2
0000r                        track     := jobnr*2+11
0000r                        wrport    := $4001
0000r 
0000r 
0000r              ; ******** Programm 1581 *********
0000r 
0000r                        .segment "utldr0"
0000r 00 03                  .addr :+          ; UTLDR Ladeadresse
0002r de                     .byte copy-:+     ; Anzahl Bytes
0003r                        .org buffer
0300               :
0300  
0300  a9 9d                  lda #<ntalk       ; Autostart-Einsprung
0302  8d b2 01               sta tlkvect       ; setzt TALK-Vektor auf
0305  a9 03                  lda #>ntalk       ; neue Routine
0307  8d b3 01               sta tlkvect+1
030a  
030a  a2 ca                  ldx #tlklen
030c  bd 69 ad     copylp:   lda tlkcode-1,x   ; kopiert TALK-Routine
030f  9d dd 03               sta copy-1,x      ; aus ROM ins RAM
0312  ca                     dex
0313  d0 f7                  bne copylp
0315  a9 48                  lda #datah-(copy+tlkbroff+2) ; korrigiert
0317  8d 65 04               sta copy+tlkbroff+1 ; Branch in TALK-Kopie
031a  a9 0f                  lda #%00001111    ; reserviert Puffer 0-3 für
031c  20 66 ff               jsr jallocbf      ; diesen Code ($0300-$06ff)
031f  18                     clc               ; verhindert erneute
0320  20 60 ff               jsr jdejavu       ; Initialisierung durch 'UI'
0323  a9 1a                  lda #%00011010
0325  8d db 01               sta srchcmd       ; beschleunigt Kopfbewegung
0328  20 03 8f               jsr getdir        ; Directory-Spur einlesen
032b  4c 5a ff               jmp jbootrtn      ; Rückkehr vom Autostart
032e  
032e  
032e               ; die durschnittlichen 46.2 µs pro empfangenem Byte mit der
032e               ; C64 PAL-Version entsprechen etwa 92 Zyklen auf der 1581 mit
032e               ; 2 MHz Takt (für NTSC müsste auf 89 Zyklen reduziert werden)
032e  
032e  a0 00        transcmd: ldy #%00000000
0330  8c 01 40               sty wrport        ;| 4 | DATA & CLOCK low setzen
0333  c1 64                  cmp (pointer,x)   ;| 6 | = nop
0335  c1 64                  cmp (pointer,x)   ;| 6 | = nop
0337  c8                     iny               ;| 2 | = 1 Kommandobyte
0338  a2 02                  ldx #%00000010    ;| 2 |
033a  8e 01 40               stx wrport        ;| 4 | DATA high setzen
033d  c1 64                  cmp (pointer,x)   ;| 6 | = nop
033f  c1 64                  cmp (pointer,x)   ;| 6 | = nop
0341  a2 0a                  ldx #%00001010    ;| 2 |
0343  8e 01 40               stx wrport        ;| 4 | DATA & CLOCK high setzen
0346  d0 0c                  bne trans1        ;| 3 | = jmp
0348  
0348  ea           trans:    nop               ;| 2 |
0349  a9 00                  lda #%00000000    ;| 2 |
034b  8d 01 40               sta wrport        ;| 4 | DATA & CLOCK low setzen
034e  8e 01 40               stx wrport        ;| 4 | CLOCK high: Synchronisation
0351  b1 64                  lda (pointer),y   ;| 5 | nächstes Byte holen
0353  ea                     nop               ;| 2 |
0354  c1 64        trans1:   cmp (pointer,x)   ;| 6 | = nop
0356  8d 45 00               sta a:temp        ;| 4 | höherwertiges Nibble retten
0359  29 0f                  and #%00001111    ;| 2 | niederwert. Nibble isolieren
035b  aa                     tax               ;| 2 |
035c  bd 8d 03               lda tab,x         ;| 4 | Nibble konvertieren
035f  8d 01 40               sta wrport        ;| 4 | Bit 0&1 senden
0362  0a                     asl               ;| 2 | Bit 2&3 in Position
0363  29 0a                  and #%00001010    ;| 2 | ATN ACK löschen
0365  aa                     tax               ;| 2 |
0366  ad 45 00               lda a:temp        ;| 4 | höherwertiges Nibble holen
0369  4a                     lsr               ;| 2 |
036a  8e 01 40               stx wrport        ;| 4 | Bit 2&3 übertragen
036d  4a                     lsr               ;| 2 |
036e  4a                     lsr               ;| 2 | höherwertiges Nibble
036f  4a                     lsr               ;| 2 | in Position bringen
0370  aa                     tax               ;| 2 |
0371  bd 8d 03               lda tab,x         ;| 4 | Nibble konvertieren
0374  8d 01 40               sta wrport        ;| 4 | Bit 4&5 übertragen
0377  0a                     asl               ;| 2 | Bit 6&7 in Position
0378  29 0a                  and #%00001010    ;| 2 | ATN ACK löschen
037a  a2 08                  ldx #%00001000    ;| 2 |
037c  ea                     nop               ;| 2 |
037d  ea                     nop               ;| 2 |
037e  88                     dey               ;| 2 | Anzahl Bytes erniedrigen
037f  8d 01 40               sta wrport        ;| 4 | Bit 6&7 senden
0382  d0 c4                  bne trans         ;|2/3| schon alle Bytes gesendet?
0384  
0384  d1 64                  cmp (pointer),y   ;| 5 | = nop
0386  8c 01 40               sty wrport        ;| 4 | CLOCK & DATA low setzen
0389  8e 01 40               stx wrport        ;| 4 | CLOCK high setzen
038c  60           return:   rts               ;| 6 | Rückkehr
038d                         .assert >transcmd = >*, error
038d  
038d  0f 07 0d 05  tab:      .repeat $10, i    ; Konvertierungs-Tabelle
0391  0b 03 09 01
0395  0e 06 0c 04
0399  0a 02 08 00
039d                         .byte ~(i<<3 | i&%0110 | i>>3) & %1111 ; ____
039d                         .endrep           ; aus Bits 3210 werden 0213
039d                         .assert >tab = >*, error
039d  
039d  78           ntalk:    sei               ; verhindert Interrupt
039e  24 ef                  bit drivenr       ; Doppelpunkt dem File-
03a0  10 2c                  bpl jtalk         ; Namen vorangestellt?
03a2  a5 76                  lda hostflg       ; im VC-20- oder
03a4  29 30                  and #%00110000    ; C128-Modus?
03a6  05 52                  ora secadr        ; Sekundäradresse <> 0?
03a8  0d 6e 02               ora dirflg        ; wird Directory geladen?
03ab  d0 21                  bne jtalk         ; ja, originale TALK-Routine
03ad  20 27 90               jsr chnopn        ; Kanal zum Lesen öffnen
03b0  b0 da                  bcs return        ; Kanal aktiv?
03b2  bd 34 02               lda status,x      ; READ-Flag gesetzt?
03b5  10 d5                  bpl return        ; nein, WRITE
03b7  bd 3b 02               lda data,x        ; 1. Byte als Startadresse
03ba  8d a7 05               sta ldstrtl+1+c64off ; LSB speichern
03bd  20 9b 90               jsr getbyte       ; nächstes Datum holen
03c0  c9 04                  cmp #>$0400       ; Autostart-Programm?
03c2  b0 0d                  bcs noauto        ; nein, dann Schnell-Laden
03c4  d6 bb                  dec chntab,x      ; ja, Zeiger zurücksetzen
03c6  a6 50                  ldx channel       ; Kanal-Nummer
03c8  ad a7 05               lda ldstrtl+1+c64off ; 1. Byte wieder
03cb  9d 3b 02               sta data,x        ; herstellen und
03ce  4c 5c ad     jtalk:    jmp talk          ; normal laden
03d1  
03d1  8d a9 05     noauto:   sta ldstrth+1+c64off ; Startadresse MSB
03d4  a6 50                  ldx channel       ; Kanal-Nummer
03d6  a0 12                  ldy #$100-(2+c64end-c64) ; Zeiger auf C64-PRG
03d8  b9 41 05     loop:     lda c64end+c64off-$100,y ; Byte holen
03db  9d 3b 02               sta data,x        ; und bereitstellen
03de               copy:                       ; TALK-Code aus ROM
03de  
03de                         .segment "utldr1"
03de  a8 04                  .addr :+          ; UTLDR Chunk Ladeadresse
03e0  ab                     .byte utilend-:+  ; Anzahl Bytes
03e1                         .org copy+tlklen  ; Lücke für TALK-Kopie
04a8               :
04a8  
04a8  c8                     iny               ; Zeiger erhöhen
04a9  f0 06                  beq spdtrans      ; letztes Byte übertragen?
04ab  4c d8 03               jmp loop          ; nein, nächstes übertragen
04ae  
04ae  4c d9 ae     datah:    jmp jjidle        ; BUS nicht aktiv
04b1  
04b1  2c 01 40     spdtrans: bit wrport        ; DATA low?
04b4  f0 0b                  beq hndshk        ; ja
04b6  88                     dey               ; nein, Y-Register erniedrigen
04b7  d0 f8                  bne spdtrans      ; Zeit abgelaufen?
04b9  
04b9  a9 80                  lda #eoi          ; ja, EOI senden, da
04bb  9d 34 02               sta status,x      ; relativ geladen wurde
04be  4c 5c ad               jmp talk          ; LOAD beenden
04c1  
04c1  8d 01 40     hndshk:   sta wrport        ; CLOCK & DATA low setzen
04c4  a9 04                  lda #%00000100
04c6  
04c6  2c 01 40     shklp:    bit wrport        ; wartet, bis CLOCK low
04c9  d0 fb                  bne shklp
04cb  
04cb  0a                     asl               ; A = %00001000
04cc  8d 01 40               sta wrport        ; CLOCK high setzen
04cf  
04cf  20 42 94               jsr getbuffp      ; holt Pufferadresse
04d2  a0 00                  ldy #$00          ; des 1. Sektors
04d4  84 64                  sty pointer       ; Zeiger auf 1. Byte setzen
04d6  b1 64                  lda (pointer),y   ; Spur
04d8  d0 07                  bne notlast       ; letzter Sektor?
04da  c8                     iny               ; ja
04db  b1 64                  lda (pointer),y   ; Anzahl Bytes des Sektors
04dd  38                     sec
04de  e9 02                  sbc #$02          ; -2 Bytes Startadresse
04e0  2c                     .byte $2c         ; lda überlesen
04e1  a9 fd        notlast:  lda #bytesect-2   ; Anzahl Bytes 1. Sektor
04e3  a2 03        :         ldx #$03          ; Zeiger auf 4. Byte
04e5  86 64                  stx pointer
04e7  d0 43                  bne first         ; = jmp
04e9  
04e9  c8           mainloop: iny               ; Zeiger auf Sektor
04ea  c5 17                  cmp track         ; gleiche Spur?
04ec  85 17                  sta track
04ee  d0 0a                  bne newtrack      ; nein, neue Spur einlesen
04f0  b1 64                  lda (pointer),y   ; Sektor
04f2  c9 14                  cmp #20
04f4  2a                     rol               ; auf gleicher Seite
04f5  45 96                  eor side          ; des Zylinders?
04f7  4a                     lsr
04f8  90 19                  bcc sideok        ; ja, Sektor übertragen
04fa  b1 64        newtrack: lda (pointer),y
04fc  85 18                  sta sector        ; Sektor retten
04fe  a9 80                  lda #read         ; Jobcode für 'Sektor lesen'
0500  85 08                  sta job           ; übergeben
0502  58                     cli               ; Kopf auf Spur
0503  00                     brk               ; Spur einlesen
0504  ea                     nop               ; Korrektur wegen brk
0505  a5 08        jobwt:    lda job           ; wartet, bis
0507  30 fc                  bmi jobwt         ; Job ausgeführt
0509  78                     sei               ; verhindert Interrupt
050a  c9 02                  cmp #$02          ; Fehler?
050c  a9 01                  lda #error        ; Kommando-Byte für Fehler
050e  b0 2e                  bcs end           ; Fehler aufgetreten
0510  a5 18                  lda sector        ; Sektor
0512  2c                     .byte $2c         ; lda überlesen
0513  b1 64        sideok:   lda (pointer),y   ; Sektor
0515  c9 14        :         cmp #20           ; grösser als 19?
0517  b0 02                  bcs subtr         ; ja, Subtraktion
0519  69 15                  adc #20+1         ; nein, Addition
051b  e9 08        subtr:    sbc #20->cache    ; berechnet Zeiger auf Cache
051d  85 65                  sta pointer+1     ; MSB Zeiger
051f  88                     dey               ; Y = 0
0520  b1 64                  lda (pointer),y   ; Spur
0522  d0 04                  bne notlast1      ; letzter Sektor?
0524  c8                     iny               ; ja
0525  b1 64                  lda (pointer),y   ; Anzahl Bytes
0527  2c                     .byte $2c         ; lda überlesen
0528  a9 ff        notlast1: lda #bytesect     ; Bytes pro Sektor normal
052a  e6 64        :         inc pointer       ; Zeiger auf 2. Byte
052c  85 54        first:    sta quantity      ; Anzahl Bytes sichern
052e  20 2e 03               jsr transcmd      ; und senden
0531  a4 54                  ldy quantity      ;| 3 | Anzahl
0533  88                     dey               ;| 2 | -1 als Zähler
0534  ea                     nop               ;| 2 |
0535  20 48 03               jsr trans         ;| 6 | Bytes übertragen
0538  84 64                  sty pointer       ; Zeiger auf Spur
053a  b1 64                  lda (pointer),y   ; letzter Sektor übertragen?
053c  d0 ab                  bne mainloop      ; nein, nächste Übertragung
053e  
053e  20 30 ad     end:      jsr delay         ; wartet 39 µs
0541  20 2e 03               jsr transcmd      ; übermittelt Kommando
0544  a5 08                  lda job           ; (0 = Ende, 1 = Fehler)
0546  f0 05                  beq okmssg        ; Fehler aufgetreten?
0548  a2 06                  ldx #jobnr        ; Fehlermeldung bereitstellen
054a  20 2d ff               jsr jerror        ; = jmp
054d  
054d  20 62 a8     okmssg:   jsr okmess        ; OK-Meldung bereitstellen
0550  4c 03 8f               jmp getdir        ; Directory-Spur einlesen
0553  
0553               utilend:  .assert * <= $0700, error ; in Puffer 0-3
0553  
0553  
0553               ; ******** Labels C64 ************
0553  
0553                         basicend  :=   $2d
0553                         bsicvect  := $e453
0553                         c64       := $0300
0553                         chroutign := $f1b4
0553                         clr       := $a660
0553                         clrchnign := $f349
0553                         exec      := $a7ae
0553                         illegqnt  := $b248
0553                         irq       := $ea31
0553                         irqign    := $ea7e
0553                         jioerror8 := $f602
0553                         ldend     := $f5aa
0553                         link      := $a533
0553                         loaderr    =    29
0553                         opsvect   := $fd15
0553                         point     :=   $ae
0553                         quant     :=   $b9
0553                         rdport    := $dd00
0553                         ready     := $a474
0553                         relad     :=   $c3
0553                         run       := $a659
0553                         screen    := $d011
0553                         secad     :=   $b8
0553                         stop      := $f6ed
0553                         sys       := $e130
0553                         sysjmp    :=   $14
0553                         tmp       := quant
0553                         warmstart := $fe66
0553  
0553               ; ******** Programm C64 **********
0553  
0553                         .segment "utldr2"
0553  53 05                  .addr utilend     ; UTLDR Ladeadresse Floppy
0555  ee                     .byte 2+c64end-:+ ; Anzahl Bytes
0556  
0556  00 03                  .addr :+          ; PRG Ladeadresse C64
0558                         .org c64
0300               :
0300  
0300  00 00                  .addr $0000       ; Endkennzeichen falls relativ geladen
0302  
0302               ; Programmstart über den STOP-Vektor, der nach jedem gespeicherten
0302               ; Byte angesprungen wird. Da zuerst nur das LSB überschrieben wird
0302               ; muss das auch eine gültige Adresse sein. Verbiegen der CLRCHN- &
0302               ; CHROUT-Vektoren macht den Code dort harmlos ausser Löschen von Z.
0302  
0302  a5 ae        stopnew:  lda point         ; Ende des Ladeprogramms erreicht?
0304  c9 ec                  cmp #<c64end
0306  f0 22                  beq start         ; ja, Schnell-Laden starten
0308  60                     rts               ; nein, weiter laden, mit Z gelöscht
0309  
0309  20 53 e4     warmnew:  jsr bsicvect      ; BASIC-Vektoren setzen
030c  4c 66 fe               jmp warmstart     ; Warmstart
030f  
030f                         .res $030f-*
030f  00                     .byte %00000000   ; Status-Register von SYS-Befehl
0310  4c 48 b2               jmp illegqnt      ; USR() Code
0313  xx                     .res $0314-*
0314  7e ea                  .addr irqign      ; IRQ-Vektor: Tastaturabfrage aus
0316                         .assert >irqign = >irq, error
0316  09 03                  .addr warmnew     ; BRK-Vektor: Warmstart
0318  09 03                  .addr warmnew     ; NMI-Vektor: Warmstart
031a  xx xx xx xx            .res $0322-*
031e  xx xx xx xx
0322  49 f3                  .addr clrchnign   ; CLRCHN-Vektor: auf rts
0324  xx xx                  .res $0326-*
0326  b4 f1                  .addr chroutign   ; CHROUT-Vektor: auf rts
0328  02 03                  .addr stopnew     ; STOP-Vektor: abfangen
032a                         .assert >jioerror8 = >stop && <stopnew = <jioerror8, error
032a                         .assert c64end-* < $100, error
032a  
032a  
032a  78           start:    sei               ; IRQ aus
032b  68                     pla               ; LSB Rücksprungadresse
032c  68                     pla               ; MSB Rücksprungadresse
032d  ad 11 d0               lda screen        ; VIC-Steuerregister 1 retten
0330  48                     pha
0331  ad 00 dd               lda rdport        ; Bit 14&15 vom VIC retten
0334  48                     pha
0335  a9 13                  lda #%00010011
0337  8d 00 dd               sta rdport        ; CLOCK high, DATA low setzen
033a  a9 00                  lda #%00000000
033c  8d 11 d0               sta screen        ; Bild aus
033f  2c 11 d0     scr:      bit screen        ; wartet, bis Rasterstrahl im
0342  10 fb                  bpl scr           ; unteren Bildrahmenbereich
0344  8d 00 dd               sta rdport        ; CLOCK low setzen
0347  
0347  a6 c3                  ldx relad         ; BASIC-Start LSB
0349  a4 c4                  ldy relad+1       ; BASIC-Start MSB
034b  a5 b8                  lda secad         ; Sekundäradresse
034d  29 09                  and #%00001001    ; 1,3,5,7-9 = absolut laden
034f  f0 08                  beq rel           ;   2,4,6   = relativ laden
0351  a2 00        ldstrtl:  ldx #$00          ; Ladeadresse LSB (wird modifiziert)
0353  a0 00        ldstrth:  ldy #$00          ; Ladeadresse MSB (wird modifiziert)
0355  86 14                  stx sysjmp        ; SYS-Adresse für
0357  84 15                  sty sysjmp+1      ; Autostart setzen
0359  86 ae        rel:      stx point         ; Zeiger setzen
035b  84 af                  sty point+1
035d  
035d  a0 01        block:    ldy #$01          ; 1 Kommandobyte
035f  2c 00 dd     wait:     bit rdport        ;| 4 |
0362  50 fb                  bvc wait          ;|2/3| wartet, bis CLOCK low
0364  2c 00 dd               bit rdport        ;| 4 | synchronisiert C64
0367  10 02                  bpl sync          ;|2/3| mit Floppy 1581
0369  e6 b9                  inc z:tmp         ;| 5 | = nop
036b  2c 00 dd     sync:     bit rdport        ;| 4 |
036e  50 02                  bvc sync1         ;|2/3|
0370  24 b9                  bit z:tmp         ;| 3 | = nop
0372  20 d1 03     sync1:    jsr get           ;| 6 | holt Kommandobyte
0375  a8                     tay               ;| 2 | = 0?
0376  f0 16                  beq endld         ;| 2 | ja, Ende
0378  88                     dey               ;| 2 | = 1?
0379  f0 13                  beq endld         ;| 2 | ja, Ladefehler
037b  84 b9                  sty quant         ;| 3 | nein, Anzahl Bytes
037d  20 d1 03               jsr get           ;| 6 | Bytes laden
0380  91 ae                  sta (point),y     ; letztes Byte auch speichern
0382  a5 ae                  lda point
0384  65 b9                  adc quant         ; Anzahl Bytes zu
0386  85 ae                  sta point         ; Zeiger addieren
0388  90 d3                  bcc block         ; kein Übertrag
038a  e6 af                  inc point+1       ; MSB erhöhen
038c  b0 cf                  bcs block         ; = jmp
038e                         .assert >wait = >sync1, error
038e  
038e  48           endld:    pha               ; Bit 0 retten
038f  20 15 fd               jsr opsvect       ; setzt Betriebssystem- &
0392  20 53 e4               jsr bsicvect      ; BASIC-Vektoren
0395  68                     pla               ; setzt bei
0396  4a                     lsr               ; Fehler Carry
0397  68                     pla               ; stellt Bit l4&15 vom
0398  8d 00 dd               sta rdport        ; VIC wieder her
039b  68                     pla
039c  8d 11 d0               sta screen        ; schaltet Bild ein
039f  58                     cli               ; Interrupt ermöglichen
03a0  b0 28                  bcs lderr         ; bei Fehler Lade-Ende
03a2  a6 b8                  ldx secad         ; Sekundäradresse
03a4  e8                     inx
03a5  8a                     txa               ; 3-6 = Autostart
03a6  29 04                  and #%00000100
03a8  f0 22                  beq ldend1        ; kein Autostart
03aa  8a                     txa
03ab  4a                     lsr
03ac  b0 0c                  bcs bscrun
03ae  20 60 a6               jsr clr           ; 1,3 = SYS-Aufruf
03b1  a9 a4                  lda #>(ready-1)   ; Rücksprungadresse MSB
03b3  48                     pha               ; auf Stapel
03b4  a9 73                  lda #<(ready-1)   ; Rücksprungadresse LSB
03b6  48                     pha               ; auf Stapel
03b7  4c 30 e1               jmp sys           ; Maschinen-PRG ausführen
03ba  
03ba  20 aa f5     bscrun:   jsr ldend         ; 2,4 = RUN-Befehl
03bd  86 2d                  stx basicend      ; BASIC-Ende setzen
03bf  84 2e                  sty basicend+1
03c1  20 59 a6               jsr run           ; CHRGET auf Programmstart
03c4  20 33 a5               jsr link          ; Zeilen binden
03c7  4c ae a7               jmp exec          ; BASIC-PRG ausführen
03ca  
03ca  a9 1d        lderr:    lda #loaderr      ; Nummer '?LOAD ERROR'
03cc  4c aa f5     ldend1:   jmp ldend         ; Ende Laderoutine
03cf  
03cf  
03cf               ; pro empfangenem Byte werden 45 oder 46 Zyklen benötigt,
03cf               ; das sind im Durchschnitt 46.2 µs für die C64 PAL-Version
03cf               ; mit 985.2486 kHz Takt (NTSC: 44.5 µs bei 1.0227271 MHz)
03cf  
03cf  91 ae        getlp:    sta (point),y     ;| 6 | legt Byte im Speicher ab
03d1  ad 00 dd     get:      lda rdport        ;| 4 | lädt Bit 0&1
03d4  4a                     lsr               ;| 2 | schiebt Byte
03d5  4a                     lsr               ;| 2 | 2 Stellen nach rechts
03d6  0d 00 dd               ora rdport        ;| 4 | fügt Bit 2&3 hinzu
03d9  4a                     lsr               ;| 2 | schiebt Byte
03da  4a                     lsr               ;| 2 | 2 Stellen nach rechts
03db  0d 00 dd               ora rdport        ;| 4 | fügt Bit 4&5 hinzu
03de  4a                     lsr               ;| 2 | schiebt Byte
03df  4a                     lsr               ;| 2 | 2 Stellen nach rechts
03e0  0d 00 dd               ora rdport        ;| 4 | fügt Bit 6&7 hinzu
03e3  2c 00 dd               bit rdport        ;| 4 | Synchronisation mit 1581
03e6  70 00                  bvs sync2         ;|2/3| +1 Zyklus falls zu schnell
03e8  88           sync2:    dey               ;| 2 | erniedrigt Anzahl Bytes
03e9  d0 e4                  bne getlp         ;|2/3| letztes Byte empfangen?
03eb  60                     rts               ;| 6 | ja, Rückkehr
03ec                         .assert >getlp = >*, error
03ec  
03ec               c64end:   .assert * <= $0400, warning
03ec