summaryrefslogtreecommitdiff
path: root/system/shard-z80-ruc-64180/1.5/src/DISK.MAC
diff options
context:
space:
mode:
Diffstat (limited to 'system/shard-z80-ruc-64180/1.5/src/DISK.MAC')
-rw-r--r--system/shard-z80-ruc-64180/1.5/src/DISK.MAC1658
1 files changed, 1658 insertions, 0 deletions
diff --git a/system/shard-z80-ruc-64180/1.5/src/DISK.MAC b/system/shard-z80-ruc-64180/1.5/src/DISK.MAC
new file mode 100644
index 0000000..56bf2f3
--- /dev/null
+++ b/system/shard-z80-ruc-64180/1.5/src/DISK.MAC
@@ -0,0 +1,1658 @@
+;
+ TITLE EUMEL fuer RUC 64180, 6502 Teil & Diskroutinen
+;
+;****************************************************************
+;
+; EUMEL 1.8.0 with RUC180-Card on BASIS 108
+;
+; 6502 DISK-Driver und Motherboard I/O
+;
+; Stand (1.8) : 14.01.87, mit neuem Puffer-Handling
+; : 27.05.87, mit Hardcopy auf SHIFT CTRL F12
+; : 26.06.87, Druckerspooler loeschen mit Task 8
+; Version 23.09.85 ./. 22.11.85
+;
+;****************************************************************
+;
+ .6502
+ .radix 16
+;
+;----------------------------------------------------------------
+;
+; Globale Variable
+;
+ GLOBAL DES6502, PRG6502, LEN65, ST6502
+;
+;----------------------------------------------------------------
+;
+; Konstanten
+;
+XOFF EQU 13 ; CTRL-S
+XON EQU 11 ; CTRL-Q
+;
+; Adressen
+;
+KeyBoard equ 0C000
+Keyext equ 0C008
+KeyStr equ 0C010
+
+VIDBNK equ 0C00C
+
+prackn equ 0C1C1
+prport equ 0C090
+
+speaker equ 0C030
+
+serial_stat equ 0C099
+SER_DAT EQU 0C098H ;Serial Interface Data
+SER_COM EQU 0C09AH ;Serial Command Register
+SER_CTR EQU 0C09BH ;Serial Control Register
+
+analog_1 EQU $C063
+analogreset EQU $C070
+
+; Floppy Hardware
+
+phase0 equ 0C080
+phase1 equ 0C082
+phase2 equ 0C084
+phase3 equ 0C086
+mtroff equ 0C088
+mtron equ 0C089
+drive0 equ 0C08A
+Q6off equ 0C08C
+Q6on equ 0C08D
+Rstate equ 0C08E
+Wstate equ 0C08F
+;
+ INCLUDE ZPAGE.INC ;Zero Page Adressen
+;
+; sonstiges
+;
+bit_z equ 24
+
+fast_step equ $0E ; etwas weniger als 3 ms Track-Wechselzeit
+
+pagerr macro adr
+ if high(*-start) ne high(adr-start)
+ .printx 'Page-Error'
+ endif
+ endm
+
+ cseg
+PRG6502:
+ .phase 0C00
+DES6502: ; 6502-Startadresse zum kopieren
+
+start: ; Label fuer Pageboundcheck
+nible1: ; Anfang des Nibble-Buffers
+ defm '6502-Teil'
+
+ST6502: ; Startadresse 6502-Teil Initialisierung
+ include BOOT.INC
+
+ include NIBLE.INC
+
+write_data
+ SEC
+ LDA Q6on,X
+ LDA Rstate,X
+ BMI wrdat99
+ LDA nible2
+ STA temp2
+ LDA #0FF
+ STA Wstate,X ; 5
+ ORA Q6off,X ; 4
+ PHA ; 3
+ PLA ; 4 [sta..sta[
+ NOP ; 2
+ LDY #04 ; 2
+wrdat1 PHA ; 3 3
+ PLA ; 4 4
+ JSR wrt_nibl1 ;+13 15 13
+ DEY ;--- 2
+ BNE wrdat1 ; 40 + 3
+ ; --- ---
+ ; 20+ 20 = 40
+
+ pagerr wrdat1
+
+ ; -1
+ LDA #0D5 ; 2
+ JSR wrt_nibl ; 15 +15
+ LDA #0AA ; 2 ---
+ JSR wrt_nibl ;+15 36
+ LDA #0AD ;---
+ JSR wrt_nibl ; 32 15
+ TYA ; 2
+ LDY #56 ; 2
+wrdat11 BNE wrdat3 ; 3
+wrdat2 LDA nible2,Y ; 0 4
+wrdat3 EOR nible2-1,Y ; 5 5
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10z ; 3 3
+ ; --- ---
+ ; 36 18
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ DEY ; 2
+ BNE wrdat2 ; 3
+ ; ---
+ ; 14 + 18 = 32
+ ; -1
+ LDA temp2 ; 3
+ NOP ; 2
+wrdat4 EOR nible1,Y ; 4 4
+ TAX ; 2 2
+ LDA to_nibble,X ; 4 4
+ LDX slot10 ; 4 4
+ ; --- ---
+ ; 32 14
+
+ STA Q6on,X ; 5
+ LDA Q6off,X ; 4
+ LDA nible1,Y ; 4
+ INY ; 2
+ BNE wrdat4 ; 3
+ ; ---
+ ; 18+ 14 = 32
+
+ pagerr wrdat11
+
+ TAX ; 2
+ LDA to_nibble,X ; 4
+ LDX slot10z ; 3
+ JSR wrt_nibl2 ; 6 15
+ LDA #0DE ; --- 2
+ JSR wrt_nibl ; 32 15
+ LDA #0AA ; ---
+ JSR wrt_nibl ; 32
+ LDA #0EB
+ JSR wrt_nibl
+ LDA #0FF
+ JSR wrt_nibl
+ LDA Rstate,X
+wrdat99
+ LDA Q6off,X
+wrdat999
+ dey
+ bne wrdat999 ; PostErase-Delay 1 ms
+
+ RTS
+
+read_hdr
+ sei
+ LDY #0FC
+ STY temp2
+rdhdr0
+ INY
+ BNE rdhdr1
+ INC temp2
+ BEQ fail
+rdhdr1
+ LDA Q6off,X
+ BPL rdhdr1
+rdhdr11 CMP #0D5
+ BNE rdhdr0
+
+ NOP
+rdhdr2 LDA Q6off,X
+ BPL rdhdr2
+ CMP #0AA
+ BNE rdhdr11
+
+ LDY #03
+rdhdr3 LDA Q6off,X
+ BPL rdhdr3
+ CMP #96
+ BNE rdhdr11
+
+ pagerr rdhdr1
+
+
+ LDA #00
+nxthByte STA chk_sum
+rdhdr4 LDA Q6off,X
+ BPL rdhdr4
+ ROL A
+ STA temp2
+rdhdr5 LDA Q6off,X
+ BPL rdhdr5
+ AND temp2
+ STA chk_in_hdr,Y
+ EOR chk_sum
+ DEY
+ BPL nxthbyte
+
+ TAY
+ BNE fail
+
+rdhdr6 LDA Q6off,X
+ bpl rdhdr6
+ cmp #0DE
+ BNE fail
+
+ NOP
+rdhdr7 LDA Q6off,X
+ BPL rdhdr7
+ CMP #0AA
+ BNE fail
+
+ CLC
+ RTS
+fail
+ SEC
+ RTS
+
+moving
+ LDY #0
+mov0 LDA Q6off,X
+ JSR mov1
+ PHA ; 3
+ PLA ; 4
+ CMP Q6off,X ; 4
+ BNE mov1 ;----
+ DEY ; 21 uS
+ BNE mov0
+mov1 RTS
+
+
+read_data
+ TXA
+ ORA #8C
+ STA ld1+1
+ STA ld2+1
+ STA ld3+1
+ STA ld4+1
+ STA ld5+1
+ LDA user_data
+ LDY user_data+1
+ STA st5+1
+ STY st5+2
+ SEC
+ SBC #54
+ BCS rddat1
+ DEY
+ SEC
+rddat1
+ STA st3+1
+ STY st3+2
+ SBC #57
+ BCS rddat2
+ DEY
+rddat2
+ STA st2+1
+ STY st2+2
+
+ LDY #20
+nxt_begin
+ DEY
+ BEQ fail
+wait_begin
+waitb0 LDA Q6off,X
+ BPL waitb0
+waitb00 EOR #0D5
+ BNE nxt_begin
+ NOP
+waitb1 LDA Q6off,X
+ BPL waitb1
+ CMP #0AA
+ BNE waitb00
+ NOP
+waitb2 LDA Q6off,X
+ BPL waitb2
+ CMP #0AD
+ BNE waitb00
+
+ LDY #0AA
+ LDA #0
+rloop1 STA temp2
+ld1 LDX Q6off+60 ; addr modified by read init !
+ BPL ld1
+ LDA to_bits-96,X
+ STA nible2-0AA,Y
+ EOR temp2
+ INY
+ BNE rloop1
+
+;
+; read nible from disk and convert to user data
+;
+ LDY #0AA
+ BNE ld2
+rloop2
+st2 STA 1000,Y
+ld2 LDX Q6off+60 ; modified by read init
+ BPL ld2
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+0,X
+ INY
+ BNE rloop2
+
+ PHA
+ AND #0FC
+ LDY #0AA
+ld3 LDX Q6off+60 ; modified by read init
+ BPL ld3
+ EOR to_bits-96,X
+ LDX nible2-0AA,Y
+ EOR to_bytes+1,X
+st3 STA 1000,Y
+ INY
+ BNE ld3
+
+ld4 LDX Q6off+60 ; modified by read init
+ BPL ld4
+ AND #0FC
+ LDY #0AC
+rloop5 EOR to_bits-96,X
+ LDX nible2-0AC,Y
+ EOR to_bytes+2,X
+st5 STA 1000,Y
+ld5 LDX Q6off+60 ; modified by read init
+ BPL ld5
+ INY
+ BNE rloop5
+ AND #0FC
+ EOR to_bits-96,X
+ LDX slot10z
+ TAY
+ BNE chk_fail
+rloop6 LDA Q6off,X
+ BPL rloop6
+ CMP #0DE
+ BEQ read_ok
+
+ pagerr wait_begin
+chk_fail
+ SEC
+ db bit_z
+read_ok
+ clc
+ PLA
+ LDY #55
+ STA (user_data),Y
+ RTS
+
+seekT lda iob_trk
+seekL
+ jsr trk_to_ph
+ cmp phase0,X
+ cmp phase1,X
+ cmp phase2,X
+ cmp phase3,X
+ LDY disk_no
+ LDA head_table,y ; da steht der Kopf jetzt
+ STA head_pos
+ lda dest_phase
+ sta head_table,y ; da soll er nachher stehen
+
+seekH
+ cmp head_pos
+ BEQ seek_rts
+ LDA #0
+ STA temp2
+seekh0 LDA head_pos
+ STA phase
+ SEC
+ SBC dest_phase
+ BEQ seekh5
+ BCS seekh1
+ EOR #0FF
+ INC head_pos
+ BCC seekh2
+seekh1 ADC #0FE
+ DEC head_pos
+seekh2 CMP temp2
+ BCC seekh3
+ LDA temp2
+seekh3 CMP #8
+ BCS seekh4
+ TAY
+seekh4 SEC
+ JSR step
+ LDA time0,Y
+ JSR step_wait
+ LDA phase
+ CLC
+ JSR step1
+ LDA time1,Y
+ JSR step_wait
+ INC temp2
+ BNE seekh0
+
+seekh5 JSR step_wait
+ CLC
+step LDA head_pos
+step1 AND #3
+ ROL A
+ ORA slot10z
+ TAX
+ LDA phase0,X
+ LDX slot10z
+seek_rts RTS
+
+;-------------------------------;
+
+make_nibl
+ LDY #56
+ LDA #0
+maken0 STA nible2-1,Y
+ DEY
+ BNE maken0
+maken1 LDX #55
+maken2 LDA (user_data),Y
+ AND #0FC
+ STA nible1,Y
+ EOR (user_data),Y
+ INY
+ CMP #02
+ ORA nible2,X
+ ROR A
+ ROR A
+ STA nible2,X
+ DEX
+ BPL maken2
+ CPY #02
+ BNE maken1
+ RTS
+
+; ds 10
+
+Dsk_RW
+ ldx #0A9 ; LDA #xx
+ lda def_byte
+ and #$20 ; Bit 5 ?
+ bne rw_0 ; Fast Step - use abs. value
+
+ ; Slow Step - use MotorOn/Off-Tables
+ ldx #0C9 ; CMP #xx
+rw_0: stx step_wait
+
+ lda #fast_step ; Set Step Rate
+ bit def_byte
+ bmi rw_1 ; Bit7: Controller-Typ
+ ; Bit7=0 => Ehring
+ lsr a ; bei Ehring 2-fache Phases => halbe Steprate
+
+rw_1: sta step_wait+1 ; Steprate
+
+ lda disk_no
+ LSR A
+ TAY
+ LDA slotn,Y
+ STA slot10
+ sta slot10z
+ adc #0
+ STA iob_drv
+
+ include TRACK.INC
+
+trk_to_ph: ; IN: A = track / OUT: A,dest_phase = phase
+ sta dest_phase
+
+; Select Side 0
+
+ bit def_byte ; Bit7: 1=Erphi-Controller
+ ; Bit6: 1=Erphi-Format
+
+ bvc ehring_format ; Bit6 = 0 => Ehring-Format
+
+ lsr dest_phase ; Erphi-Format
+ bcc side0
+
+; Select Side 1
+; Erphi: mtroff, Q6on, mtron
+; Ehring: mtroff,mtron
+
+side1: lda mtroff,x
+ bit def_byte
+ bpl side1_2
+ ; Erphi-Side-1-Select
+ lda Q6on,x
+side1_2:
+ lda mtron,x
+ jmp ph_mult
+
+ehring_format:
+ cmp #$50 ; Track >= 80 ?
+ bcc side0 ; nein: Select Side 0
+
+ sbc #$50
+ sta dest_phase
+ jmp side1
+
+; Select Side 0
+; Ehring: lda cn00,x
+; Erphi : mtroff, Q6off, mtron
+
+side0: bit def_byte
+ bmi erphi_s0 ; Bit7 = 1 => Erphi-Controller
+
+ txa ; Ehring-Side-0-Select
+ lsr a
+ lsr a
+ lsr a
+ lsr a
+ ora #$C0
+ sta ehr_sel+2
+
+ehr_sel:lda $C600
+ jmp ph_mult
+
+erphi_s0: ; Erphi-Side-0-Select
+ cmp mtroff,x
+ cmp Q6off,x
+ cmp mtron,x
+
+ph_mult:
+ lda def_byte ; Bit 0..1: 0 = 1 Step/Track
+ and #03 ; 1 = 2 Steps/Track
+ tay ; 2 = 4 Steps/Track
+ beq ph_mult2
+
+ph_mult1:
+ asl dest_phase
+ dey
+ bne ph_mult1
+
+ph_mult2:
+ lda dest_phase
+ rts
+
+;---------------------------------------------------------------------------
+;
+; D I S K R W
+; Eingang: iob_trk, sektor, def_byte, disk_no, param, last_track
+; dma, ilv_tbl,
+; Ausgang: iob_err
+; Daten: x000..xFFF (Ein Track, Sektoren in log. Reihenfolge)
+; 64180 darf nicht auf den Applebus, Aufruf mit JSR
+;
+;---------------------------------------------------------------------------
+
+DISKRW:
+ jsr lock_bus
+
+ lda iob_trk ; Track fuer Read/Write
+ bit param ; 0 = Write, FF = Read
+ bpl writecmd
+ cmp last_track ; Muss auf neuen Track positioniert
+ bne readtrack ; werden ?
+
+ ldy sektor
+ ldx ilv_tble,y
+ lda sec_tble,x
+ beq readtrack ; Sektor nicht ok
+ ldx ilv_tble+1,y
+ lda sec_tble,x
+ beq readtrack
+
+ lda #00 ; Nein, somit auch kein Lesefehler
+ sta iob_err
+ jmp unlock_bus
+
+readtrack:
+ sei
+ lda #10 ; Track muss ganz neu gelesen werden
+ sta sec_cnt ; das sind 16 Sektoren a 256 Byte
+ lda #00 ; Kennzeichen fuer Einlesen
+ ldx #0F
+sec_1_loop: sta sec_tble,x ; Sektortabelle = Kennzeichen setzen
+ dex
+ bpl sec_1_loop
+ bmi readwrite
+
+writecmd:
+ sei
+ ldx #02 ; Bei Write nur 512 Byte schreiben
+ stx sec_cnt
+ ldx #0F
+ lda #$FF ; Kennzeichen fuer 'nicht Einlesen'
+sec_2_loop: sta sec_tble,x
+ dex
+ bpl sec_2_loop
+
+ ldy sektor ; gewuenschter 1. Sektor
+ ldx ilv_tble,y ; logisch --> physisch umrechnen
+ lda #00 ; Kennzeichen 'Sektor schreiben'
+ sta sec_tble,x
+ ldx ilv_tble+1,y ; 2. Sektor logisch --> physisch
+ sta sec_tble,x ; Auch schreiben
+
+ lda last_track
+ cmp iob_trk ; Anderer Track als der letzte ?
+ beq readwrite
+ jsr readwrite ; Ja
+ lda #$FF ; Muss bei Read neu eingelesen werden,
+ ; da die anderen 14 Sektoren zum
+ ; letzen Track gehoeren
+ sta last_track
+ rts
+
+readwrite:
+
+ lda #00
+ tay
+ tax
+interlv_2:
+ ora #dma_4k ; Cachebereich (4k) fuer Track
+ sty dma,x
+ inx
+ sta dma,x
+ inx
+ clc
+ adc #0B ; Interleave 3
+ and #0F ; MOD 16
+ cpx #20 ; 16 Sektoren
+ bne interlv_2
+
+ lda #0F ; Step Rate
+ sta iob_err
+ jsr dsk_rw ; Disk Operation
+ lda iob_err ; Fehlerkennzeichen
+ beq no_err
+
+ ldy sektor
+ ldx ilv_tble,y
+ lda sec_tble,x
+ beq is_err ; Fehler im 1. Teil des Blocks ?
+ ldx ilv_tble+1,y
+ lda sec_tble,x
+ beq is_err ; Fehler im 2. Teil des Blocks ?
+ ; nein,
+ lda #0
+ sta iob_err ; Zumindest dieser Block ok
+ beq no_err ; Always
+
+is_err:
+ lda #$FF ; Track muss neu gelesen werden
+ db bit_a ; Skip 2 Bytes
+no_err: lda iob_trk ; last_track := track
+ sta last_track
+ jmp unlock_bus
+
+;----------------------------------------------------------------------------
+;
+; A N A L 6 5
+; Eingang: param = 1..4 (Analogschalternummer)
+; Ausgang: analogwert = 0..255
+;
+;---------------------------------------------------------------------------
+
+ANAL65:
+ sei
+ jsr lock_bus
+ ldx param ; Nummer des Analogports
+ lda analogreset ; Timer starten
+ ldy #00
+ nop
+ nop
+readanalog:
+ lda analog_1,x ; Analogwert lesen
+ bpl anaready
+ iny
+ bne readanalog ; Bis Bit 7 auf 0
+ pagerr readanalog
+ dey ; Maximum 255
+
+anaready: sty analogwert
+ cli
+ jmp unlock_bus
+
+;
+ INCLUDE GRAFIK65.MAC
+;
+irqvec:
+ sta Asave ; Akku retten
+ pla
+ pha
+ and #10 ; BRK -Bit ?
+ bne brkirq
+ lda Asave
+ jmp irq ; Interrupt ausfuehren
+
+brkirq:
+ lda main_ROM
+ lda Asave
+ jmp BREAK ; Alte BREAK-Routine
+
+resvec:
+ lda main_ROM ; ROM einschalten
+ jmp RESET ; Alte RESET-Routine
+
+;****************************************************************
+;
+; B E L L
+;
+; => Akustisches Signal
+
+beep sei
+ jsr lock_bus
+ lda #$32 ; Laenge
+ ; Frequenz = 5000/X Hz
+
+beep1 ldx param ; 3
+beep2 ldy #$12 ; 2
+beep3 dey ; 2
+ bne beep3 ; + 3
+ ; ----
+ ; 89 = 5 * 18 - 1
+ nop ; 2
+ nop ; 2
+ nop ; 2
+ dex ; 2
+ bne beep2 ; 3
+ ; ----
+ ; 102 * X * 0.9775 us
+ ; = 99.7ms (f ~ 10kHz/X)
+ ; -1 (Branch)
+ bit speaker ; 4
+ sec ; 2
+ sbc #1 ; 2
+ bne beep1 ; 3
+ ; -----
+ ; (14 + 102 * X) * A States Dauer
+ ; 0.9775 * (14 + 102 * X) * A us
+ cli
+ jmp unlock_bus
+
+;*******************************************************************
+;
+; Zugriffskontrolle fuer 64180 auf 6502-Bus
+;
+lock_bus:
+ lda #$FF
+ sta bus_locked
+ ldx SLOT180
+ lda wait180,x
+ rts
+
+unlock_bus:
+ lda #$00
+ sta bus_locked
+ ldx SLOT180
+ lda start180,x
+ rts
+
+;*******************************************************************
+;
+; Input-Buffer Handler
+;
+; Der Buffer darf nicht voll sein!
+; Interrupts bei Receive-Buffer disabled
+; Eingang: A = Zeichen
+; X = Bufferdescriptor Offset
+; Ausgang: X intakt
+; A veraendert
+; SEC, wenn Puffer voll war
+putbuf:
+ sei
+putbuf0:
+ pha
+ lda free,x ; Test, ob Puffer voll
+ ora free+1,x
+ beq putbuf4
+ pla
+
+ sta (in,x) ; Zeichen in Puffer schreiben
+
+ inc in,x ; Schreibzeiger erhoehen
+ bne putbuf1
+ inc in+1,x
+
+ lda in+1,x ; Puffer-Ende ?
+ cmp end,x
+ bcc putbuf1
+ lda beg,x ; Ringpuffer, wieder auf Pufferanfang setzen
+ sta in+1,x
+
+putbuf1:
+ dec wait_flg ; Warten, bis update vorbei
+ inc full,x ; Belegten Platz vergroessern
+ bne putbuf2
+ inc full+1,x
+
+putbuf2: ; Dieser Wert wird auch von FROUT benutzt!
+ lda free,x ; Freiplatz verringern
+ bne putbuf3
+ dec free+1,x
+putbuf3:
+ dec free,x
+ inc wait_flg ; Update gelaufen
+ clc ; Zeichen uebernommen
+ rts
+
+putbuf4:
+ pla
+ sec
+ rts ; Puffer war voll
+
+;*******************************************************************
+;
+; Output-Buffer Handler
+;
+; Interrupts bei Transmit-Buffer disabled
+; Der Buffer darf nicht leer sein!
+; Eingang: X = Bufferdescriptor Offset
+; Ausgang: X intakt
+; A = Zeichen
+; SEC, wenn Puffer leer war
+getbuf:
+ sei
+getbuf0:
+ sec
+ lda full,x
+ ora full+1,x
+ beq getbuf4 ; Test, ob Puffer leer ist
+
+ lda (out,x) ; Zeichen aus Puffer lesen
+ pha
+
+ inc out,x
+ bne getbuf1
+ inc out+1,x ; Lesezeiger erhoehen
+
+ lda out+1,x
+ cmp end,x
+ bne getbuf1
+ lda beg,x
+ sta out+1,x ; Ringpuffer, Zeiger wieder auf Pufferanfang
+
+getbuf1:
+ dec wait_flg ; Warten, bis Update vorbei
+ inc free,x
+ bne getbuf2
+ inc free+1,x ; Freien Platz vergroessern
+getbuf2:
+
+ lda full,x
+ bne getbuf3
+ dec full+1,x
+getbuf3:
+ dec full,x ; Belegten Platz verringern
+ inc wait_flg ; Update vorbei
+
+ pla
+ clc
+
+getbuf4: ; A enthaelt 00, wenn Puffer leer war
+ rts
+
+;****************************************************************
+;
+; => Drucker-Spooler
+;
+;------------------------------------------------------------------
+;
+; Zeichen aus Druckerspooler an Drucker senden
+;
+spochc:
+ lda prackn
+ bmi chcend ; Printer ready ?
+
+ ldx #pbuf ; Printer Buffer
+ jsr getbuf0 ; Ohne SEI
+ bcs chcend ; Nichts auszugeben, fertig
+
+ sta prport ; Zeichen ausgeben
+ jmp spochc ; Bis nichts mehr moeglich ist
+
+chcend:
+ rts
+
+;--------------------------------------------------------------------
+;
+; Zeichen in Druckerpuffer schreiben
+
+bufin:
+ ldx #pbuf ; Zeichen geht verloren, wenn Puffer voll
+ jmp putbuf0 ; Zeichen in Puffer schreiben
+
+
+;****************************************************************
+;
+; => Ausgabe Spooler fuer serielle Schnittstelle
+;
+;-----------------------------------------------------------------
+;
+; Zeichen aus dem Transmitbuffer senden
+;
+;spsero:
+; LDA serial_stat
+; AND #10 ; Transmit Data Register empty ?
+; BEQ schend ; serielles Interface nicht bereit
+
+spserok: ; Einsprung fuer Transmitinterrupt
+
+ LDA SerFlg ; Ausgabe Stop ?
+ BMI dis_tx ; Ja -> nichts ausgeben
+
+ ldx #tbuf ; Transmitbuffer
+ jsr getbuf ; Zeichen aus Puffer lesen
+ bcs dis_tx ; Transmitter disabled, wenn Puffer leer
+
+ sta SER_DAT ; Zeichen ausgeben
+schend:
+ rts
+
+dis_tx:
+ lda ser_com
+ and #$F3
+ ora #$08 ; Transmit Interrupt aus
+ sta ser_com
+ rts
+
+;---------------------------------------------------------------------
+;
+; Zeichen in den Transmitbuffer schreiben
+sbufin:
+ ldx #tbuf ; Zeichen in Transmitbuffer schreiben
+ jsr putbuf ; Zeichen geht verloren, wenn Puffer voll
+ cli ; Wird nicht in Interruptrotinen aufgerufen
+
+ lda ser_com
+ and #$F3
+ cmp #$04 ; War Transmitinterrupt enabled ?
+ beq sbufin1
+
+ ora #$04 ; Enable Transmit Interrupt
+ sta ser_com
+sbufin1:
+ rts
+
+;****************************************************************
+;
+; Eingabe Spooler fuer serielle Schnittstelle
+;
+;-----------------------------------------------------------------
+;
+; Zeichen in A in den Receivebuffer schreiben
+rxser:
+ bit A_FLG ; Ausgabeflusskontrolle
+ bpl rxser3 ; XON/XOFF interpretieren ?
+
+ cmp #XON
+ bne rxser4
+
+ lda #$7F
+ and SerFlg ; Transmitter starten
+ sta SerFlg ; Bit 7 := 0
+
+ lda ser_com
+ and #$F3
+ ora #$04
+ sta ser_com
+ rts
+
+rxser4:
+ cmp #XOFF
+ bne rxser3 ; war weder XON noch XOFF
+
+ lda #80
+ ora SerFlg ; Transmit-IRQ schaltet sich selbst aus
+ sta SerFlg ; Bit 7 := 1
+ rts
+
+rxser3:
+ ldx #rbuf
+ jsr putbuf ; Zeichen geht verloren, wenn Puffer voll
+ bcs rx_rts
+
+ lda free+1+rbuf
+ bne rx_rts ; Noch genug Platz
+ lda free+rbuf
+ cmp #10
+ bne rx_rts ; Mehr als 16 Zeichen frei
+ ; Flusskontrolle durchfuehren
+ bit E_FLG ; Eingabeflusskontrolle
+ bpl rxser1
+ ; XOFF senden
+ lda #XOFF
+ jsr DSerOut
+
+rxser1:
+ bit E_FLG
+ bvc rx_rts
+ ; DTR low legen
+ lda ser_com
+ and #$FE
+ sta ser_com
+
+rx_rts: rts
+
+
+
+;--------------------------------------------------------------------
+;
+; Zeichen aus Receivepuffer lesen an 64180 senden
+;
+rxout:
+ lda INTPAR1
+ bne rxout_rts ; Letzer Interrupt noch nicht quittiert
+
+ bit bus_locked
+ bmi rxout_rts ; 64180 darf nicht auf den Bus
+
+ bit IFLG ; "stop" - Zustand
+ bmi rxout_rts ; Kein Inputinterrupt
+
+ ldx #rbuf
+ jsr getbuf ; Zeichen lesen
+ bcs rxout_rts ; Puffer ist leer
+
+ ldx #5 ; Kanal 5: serielle Schnittstelle
+ ldy err5_bits ; Fehlerbits (passen nicht zum Zeichen)
+ jsr TO180 ; Zeichen im Akku
+
+ ldy #0
+ sty err5_bits ; loeschen
+
+ lda full+1+rbuf
+ bne rxout_rts ; Noch zuviel im Puffer
+ lda full+rbuf
+ cmp #10
+ bne rxout_rts ; Noch mehr als 16 Zeichen im Puffer
+
+ bit E_FLG
+ bpl rxout2
+
+ lda #XON ; XON senden
+ jsr DSerOut
+
+rxout2:
+ bit E_FLG
+ bvc rxout_rts
+ ; DTR high legen
+ lda ser_com
+ ora #01
+ sta ser_com
+
+rxout_rts:
+ rts
+
+
+;-------------------------------------------------------------------
+;
+; Direkte Ausgabe auf der seriellen Schnittstelle
+;
+DSerOut:
+ pha
+
+ lda ser_com
+ and #$F3
+ ora #08 ; Transmitter on, Tx_IRQ off
+ sta ser_com
+
+Wai_empty:
+ LDA serial_stat
+ AND #10 ; Transmit Data Register empty ?
+ BEQ Wai_empty ; warten bis Transmitter empty ->
+
+ pla
+ STA SER_DAT
+
+ lda ser_com
+ and #$F3
+ ora #$04
+ sta ser_com ; Transmitter on, TX_IRQ on
+
+ RTS
+
+
+;************************************************************************
+;
+; => Interrupt: Tastatur/V24
+;
+;-------------------------------------------------------------------------
+;
+; Interrupt-Handler
+;
+IRQ:
+ sta ASave
+ stx XSave
+ sty YSave
+
+ bit keyboard ; Taste gedrueckt ?
+ bpl irq_1
+
+ jsr keyIRQ
+
+irq_1:
+ lda serial_stat
+ bpl irqret
+
+ pha
+ and #08 ; Receive Data Register full ?
+ beq irq_2
+
+ pla
+ pha
+ jsr receive_irq
+
+irq_2:
+ pla
+ pha
+ and #10 ; Transmit Data Register empty ?
+ beq irq_3
+
+ jsr spserok ; Zeichen aus Transmitbuffer senden
+
+irq_3:
+ pla
+ pha
+ and #18
+ bne irq_4
+ ; External Status Change IRQ
+ pla
+ pha
+ jsr status_irq
+
+irq_4:
+ pla
+IRQret:
+ ldy YSave
+ ldx XSave
+ lda ASave
+ rti ; Pull Old Status and Return
+
+;-------------------------------------------------------------------
+;
+; Status Change - Interrupt
+;
+; Eingang: A = serial_stat
+;
+status_irq:
+ bit A_FLG ; Ausgabe Flusskontrolle (DSR beachten)
+ bvc status1
+
+ and #40 ; DSR beobachten
+ beq status2 ; -DSR low, Transmitter starten
+
+ lda #$7F ; Bit 7 := 0
+ and SerFlg
+ sta SerFlg
+
+ lda ser_com
+ and #$F3
+ ora #$04 ; Transmitter on, Tx_IRQ on
+ sta ser_com
+status1:
+ rts
+
+status2: ; -DSR high, Transmitter stoppen
+ lda #80
+ ora SerFlg ; Transmitter stoppt sich selbst
+ sta SerFlg
+ rts
+
+;-------------------------------------------------------------------
+;
+; Receiver - Interrupt
+; Eingang: Y = ser_dat
+; A = serial_stat
+;
+receive_irq:
+ and #7 ; Fehlerbits ausmaskieren
+ ldy ser_dat ; Zeichen einlesen
+
+ bit SerFlg ; Letztes Zeichen war Break
+ bvc receive1
+
+ pha
+ lda #2 ; Break
+ ora err5_bits
+ sta err5_bits ; Break empfangen
+
+ lda #$BF
+ and SerFlg ; Break Bit 6 := 0
+ sta SerFlg
+ pla
+
+ cpy #2 ; SV-Call
+ beq sv_call
+ cpy #'W' ; BREAK - W = control ('weiter') simulieren
+ beq weiter ; WEITER
+ cpy #'R' ; BREAK - R = RESET
+ beq reset_sys ; RESET
+ cpy #'S' ; BREAK - S = Shutup
+ bne receive1 ; SHUTUP
+
+ pha
+ ldx #'S' ; Shutup-Kennzeichen
+ tay
+ jsr TO180 ; Shutup - Interrupt
+ pla
+
+receive1:
+ cmp #2 ; Framing Error ?
+ bne receive2
+ cpy #0 ; und Zeichen 00 = Break
+ bne receive2
+
+ lda #$40
+ ora SerFlg ; Break vermerken
+ sta SerFlg
+ rts
+
+sv_call:
+ jsr weiter
+ ldy #0
+ ldx #5
+ lda #2 ; CTRL-B
+ jmp TO180
+
+weiter:
+ lda #0
+ sta INTPAR1 ; Interrupt als quittiert ansehen
+ lda #7F
+ and IFLG
+ sta IFLG
+ rts
+
+receive2:
+ tax
+ lda errbit_tab,x ; ACIA-Fehlerbits --> EUMEL Fehlerbits
+ ora err5_bits
+ sta err5_bits ; Fehler vermerken
+
+ tya ; Zeichen war in Y
+ jsr rxser ; Zeichen in Receivepuffer schreiben
+
+ jmp rxout ; Versuchen an 64180 zu senden
+
+;-------------------------------------------------------------------------
+;
+; Fehlerbits
+;
+errbit_tab:
+ db 0, 4, 4, 4, 1, 5, 5, 5
+ ; EUMEL: Bit 0= Overrun, Bit 1= Break, Bit 2= Parity/Framing
+
+;*******************************************************************
+;
+; Remote - Reset
+;
+reset_sys:
+ sei
+ ldx #rescodelen-1
+resetsysa:
+ lda rescode,x
+ sta 0,x
+ dex
+ bpl resetsysa
+
+ ldx SLOT180
+ lda stop180,x
+ nop
+ lda start180,x
+ nop
+ lda stop180,x
+ jmp resvec
+
+rescode:
+ db $AF, $F3, $ED, $39, $00, $ED, $39, $00, $ED, $76
+rescodelen equ $-rescode
+
+ ; SYSEND:
+ ; XOR A
+ ; DI
+ ; OUT0 (CNTLA0),A
+ ; OUT0 (CNTLA0),A
+ ; SLP
+
+;------------------------------------------------------------------
+;
+; Keyboard - Interrupt
+;
+keyIRQ:
+ lda KeyBoard
+ asl a
+
+ tax ; X = 6543 210O
+ lda KeyExt
+ asl a ; Carry = Bit 7
+ txa
+ ror a
+ sta KeyStr ; Strobe loeschen
+
+ bit bus_locked
+ bmi readkey0 ; Nur SHUTUP/RESET erlaubt
+
+ cmp #$C2 ; F2 = SV-CALL
+ bne readkey0a
+ jsr readkey0b
+
+ lda #$C2
+ ldx #1
+ jmp TO180
+
+readkey0a:
+ cmp #$BC ; SHIFT CTRL F12 = HCOPY-KEY
+ bne readkey0c
+ jmp HCOPY
+
+readkey0c:
+ cmp #$BD ; SHIFT CTRL F13 = WEITER-KEY
+ bne readkey0
+readkey0b:
+ lda #0
+ sta INTPAR1 ; Interrupt als quittiert ansehen
+ lda #$BF ; Bit 6 loeschen
+ and IFLG
+ sta IFLG
+ rts
+
+readkey0:
+ cmp #$BE ; SHIFT CTRL F14 = SHUTUP-KEY
+ bne readkey1
+ ldx #'S' ; Kennzeichen fuer Shutup
+ jmp TO180 ; Shutup-Interrupt
+
+readkey1:
+ cmp #$BF ; SHIFT CTRL F15 = RESET-KEY
+ bne readkey2
+ jmp reset_sys ; Keine Rueckkehr
+
+readkey2:
+ ldx KeyIn
+ inx
+ cpx KeyOut
+ bne readkey3
+ ; Tastaturpuffer Overflow
+ lda err1_bits ; Kanal 1 Fehlerbits
+ ora #1
+ sta err1_bits ; Overrun-Error
+
+ ldx #$0A ; Kurzer Beep: Buffer full
+ ldy #$10
+ jmp beep1
+
+readkey3:
+ dex
+ sta KeyBuf,x
+ inc KeyIn
+ ; Versuchen an 64180 zu senden
+
+;----------------------------------------------------------------
+;
+; Zeichen aus Keyboard-Buffer holen
+;
+getkey:
+ ldx INTPAR1 ; letzter Interrupt quittiert ?
+ bne Getret
+
+ bit bus_locked
+ bmi Getret
+
+ bit IFLG ; "stop" - Zustand ?
+ bvs Getret ; Kein Inputinterrupt
+
+ sei
+ ldx KeyOut
+ cpx KeyIn
+ beq GetRet ; Puffer leer
+
+ lda KeyBuf,x
+ inc KeyOut
+
+ ldx #1 ; Kanal 1, Zeichen muss da sein
+ ldy err1_bits ; Overrun Bit
+ jsr TO180 ; 64180 Interrupt
+
+ ldy #0
+ sty err1_bits
+
+GetRet:
+ rts
+
+;****************************************************************
+;
+; Texthardcopy auf Basis-Parallel
+; (Interrupt muessen disabled sein)
+; (Nur moeglich, wenn Druckerspooler leer, 64180 wird gestoppt)
+;
+HCOPY:
+ lda pbuf+full
+ ora pbuf+full+1
+ bne getret ; Kein Hardcopy, da Spooler nicht leer ist.
+
+ jsr lock_bus ; 64180 vom Dienst suspendieren
+ lda #$0D
+ jsr bufin ; CR an Drucker
+
+ ldx #0
+hcopy2:
+ ldy #0 ; 1. Spalte
+hcopy1:
+ txa
+ pha
+ tya
+ pha
+ jsr bascalc ; Zeichen an der Position lesen
+ and #$7F ; Inversbit ausblenden
+ jsr bufin ; Zeichen an Drucker
+ pla
+ tay
+ pla
+ tax
+
+ iny
+ cpy #$50 ; 80. Spalte ?
+ bne hcopy1
+
+ txa
+ pha
+
+ lda #$0D ; CRLF an Drucker
+ jsr bufin
+ lda #$0A
+ jsr bufin
+ jsr spochc ; Spooler erstmal leeren
+
+ pla
+ tax
+ inx
+ cpx #$18 ; 24. Zeile ?
+ bne hcopy2
+
+ jmp unlock_bus ; 64180 darf wieder arbeiten
+
+;------------------------------------------------------------------------
+;
+; Berechnet Adresse der Bildschirmposition (A,X) nach basl/bash
+; Holt Zeichen --> A
+; Static/Dynamic - Switch ggf. veraendert
+;
+bascalc:
+ lsr a
+ tay ; Y DIV 2
+ sta VIDBNK ; default even Y
+ bcc bascalc1
+ sta VIDBNK+1 ; odd Y
+bascalc1:
+ txa
+ lsr a
+ and #3
+ ora #4 ; Page 0400..0BFF
+ sta bash ; High
+ txa
+ and #$18
+ bcc bascalc2
+ ora #$80
+bascalc2:
+ sta basl ; Low
+ asl a
+ asl a
+ ora basl
+ sta basl
+ lda (basl),y
+ rts
+
+;****************************************************************
+;
+; Interrupts zum 64180 (Inputinterrupts)
+; moeglich von Tastatur (Kanal 1) und seriellem Interface (Kanal 5)
+; Shutup-Interrupt mit X = 'S'
+; Ausgang: X veraendert
+;
+TO180:
+ php
+ sei
+ STA intpar2 ; Zeichen
+ STY intpar3 ; Fehlerbits
+ STX intpar1 ; Kanalnr.
+ LDX SLOT180
+ LDA INT180,X ; 64180 Interrupt erzeugen
+ LDA intpar2
+ plp ; Interrupt Flag
+ RTS
+
+;****************************************************************
+;
+; Drucker Spooler loeschen
+;
+init_pbuf:
+ ldx #initab_len
+ploop: lda pbuf_ini,x
+ sta pbuf,x
+ dex
+ bpl ploop
+ rts
+
+pbuf_ini:
+ DW (DBUFEND - DBUFBEG) * 100H, 0
+ DW DBUFBEG * 100H, DBUFBEG * 100H
+ DB DBUFBEG, DBUFEND
+initab_len EQU *-pbuf_ini-1 ; Alle gleich Lang
+
+
+;****************************************************************
+;
+; Puffer pollen
+;
+polling:
+ jsr spochc ; Zeichen aus Printer Spooler ?
+
+; lda full+tbuf
+; ora full+tbuf+1
+; beq polling2
+
+; jsr spsero ; Zeichen aus Transmitbuffer senden
+; cli
+
+;polling2:
+ lda INTPAR1 ; letzter Interrupt quittiert ?
+ bne polling1 ; Puffer garnicht erst testen
+ ; Polling: Interrupts an 64180
+
+ jsr getkey ; Zeichen aus Tastatur-Buffer
+ cli
+
+ lda full+rbuf
+ ora full+rbuf+1
+ beq polling1
+
+ jsr rxout ; Zeichen aus Receive-Buffer
+ cli
+
+polling1:
+ rts
+
+
+;****************************************************************
+;
+; Hauptschleife des 6502: wartet auf Tasks
+;
+; Task 1 : Disk R/W
+; 2 : Bell
+; 3 : Char zum Drucker(spooler)
+; 4 : Char zum seriell Spooler
+; 5 : Direktausgabe auf serieller Schnittstelle
+; 6 : Analog I/O
+; 7 : Grafik
+;
+task_end:
+; 8 : Druckerspooler loeschen
+
+ lda #0
+ sta task
+ sta bus_locked ; Nicht mehr gesperrt
+
+
+task_loop:
+ cli
+ jsr polling ; Puffer pollen
+
+ lda task
+ beq task_loop
+
+ cmp #1
+ bne task_lp1
+
+ jsr DISKRW ; Disk I/O
+ jmp task_end
+
+task_lp1:
+ cmp #2
+ bne task_lp2
+
+ jsr Beep
+ jmp task_end
+
+task_lp2:
+ cmp #3
+ bne task_lp3
+
+ lda param
+ jsr bufin ; in Spooler-Buffer
+ jmp task_end
+
+task_lp3:
+ cmp #4
+ bne task_lp4
+
+ lda param
+ jsr sbufin ; Output to serial Interface
+ jmp task_end
+
+task_lp4:
+ cmp #5
+ bne task_lp5
+
+ lda param
+ jsr DSerOut ; direkte Ausgabe auf ser. Schnittstelle
+ jmp task_end
+
+task_lp5:
+ cmp #6
+ bne task_lp6
+
+ jsr ANAL65 ; Analog I/O
+ jmp task_end
+
+task_lp6:
+ cmp #7
+ bne task_lp7
+
+ JSR GRAFIK ; Grafik I/O
+ jmp task_end
+
+task_lp7:
+ cmp #8
+ bne task_end
+
+ jsr init_pbuf ; Drucker Spooler loeschen
+ jmp task_end
+
+
+ defm 'Ende vom SHard'
+LEN65 EQU $-start
+ IF $ GE 2000
+ .printx '6502-Modul in Grafikseite 1!'
+ ENDIF
+ end
+ \ No newline at end of file