From dd159cc607d10cb5ff2f1bf7eac927f8524e1ad7 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Fri, 22 Mar 2024 22:11:25 +0100 Subject: [PATCH 01/27] 1541 ROM calls documented using All About Your 1541 http://unusedino.de/ec64/technical/aay/c1541/index.htm --- drv/drv1541.s | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drv/drv1541.s b/drv/drv1541.s index 378f303b..b26cd8f7 100644 --- a/drv/drv1541.s +++ b/drv/drv1541.s @@ -1298,7 +1298,7 @@ Drv_ExitTurbo: jsr D_DUNK4_1 LoadB $33, 0 sta $1800 - jsr $f98f + jsr $f98f ; turn drive motor off LoadB $1c0c, $ec pla pla @@ -1435,7 +1435,7 @@ Drv_NewDisk_4: Drv_NewDisk_5: txa Drv_NewDisk_6: - jsr $f24b + jsr $f24b ; Establish number of sectors per track (in: A=track, out: A=number of sectors on that track) sta $43 Drv_NewDisk_7: lda $1c00 @@ -1528,11 +1528,11 @@ D_DUNK11_1: beq D_DUNK11_3 cmp #$30 beq D_DUNK11_2 - jmp $f4ca + jmp $f4ca ; Test command code further ($00=read, $10=write, $20=verify, other=read block header) D_DUNK11_2: - jmp $f3b1 + jmp $f3b1 ; Read block header, verify ID D_DUNK11_3: - jsr $f5e9 + jsr $f5e9 ; Calculate parity for data buffer ($30) sta $3a lda $1c00 and #$10 @@ -1540,11 +1540,11 @@ D_DUNK11_3: lda #$08 bne D_DUNK11_9 D_DUNK11_4: - jsr $f78f - jsr $f510 + jsr $f78f ; Convert 260 bytes (256+4) to 325 bytes group code buffer $01BB-$01FF and ($30) + jsr $f510 ; Read block header (wait until needed block header arrives) ldx #9 D_DUNK11_5: - bvc D_DUNK11_5 + bvc D_DUNK11_5 ; skip over sync clv dex bne D_DUNK11_5 @@ -1565,14 +1565,14 @@ D_DUNK11_6: bne D_DUNK11_6 ldy #$bb D_DUNK11_7: - lda $0100,y + lda $0100,y ; write data bvc * clv sta $1c01 iny bne D_DUNK11_7 D_DUNK11_8: - lda ($30),y + lda ($30),y ; write data, continued bvc * clv sta $1c01 @@ -1593,9 +1593,9 @@ D_DUNK12: lda $20 and #$20 bne D_DUNK12_3 - jsr $f97e + jsr $f97e ; Turn drive motor on D_DUNK12_1: - ldy #$80 + ldy #$80 ; delay until it spins up D_DUNK12_2: dex bne D_DUNK12_2 From 48b2cc283a57cb43898cb3fea1d33b4dad1642c8 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sat, 23 Mar 2024 12:20:47 +0100 Subject: [PATCH 02/27] 1541 disk driver with serial communication replaced by parallel (standard: VIA pins 2-9,18,39) cable --- Makefile | 5 + config.inc | 2 + drv/drv1541parallel.cfg | 11 + drv/drv1541parallel.s | 1552 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 1570 insertions(+) mode change 100755 => 100644 Makefile create mode 100644 drv/drv1541parallel.cfg create mode 100644 drv/drv1541parallel.s diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 5e4d6636..6c918043 --- a/Makefile +++ b/Makefile @@ -233,6 +233,7 @@ endif DRIVER_SOURCES= \ drv/drv1541.bin \ + drv/drv1541parallel.bin \ drv/drv1571.bin \ drv/drv1581.bin \ input/joydrv.bin \ @@ -269,6 +270,7 @@ PREFIXED_RELOCATOR_OBJS = $(addprefix $(BUILD_DIR)/, $(RELOCATOR_OBJS)) ALL_BINS= \ $(BUILD_DIR)/kernal/kernal.bin \ $(BUILD_DIR)/drv/drv1541.bin \ + $(BUILD_DIR)/drv/drv1541parallel.bin \ $(BUILD_DIR)/drv/drv1571.bin \ $(BUILD_DIR)/drv/drv1581.bin \ $(BUILD_DIR)/input/joydrv.bin \ @@ -379,6 +381,9 @@ endif $(BUILD_DIR)/drv/drv1541.bin: $(BUILD_DIR)/drv/drv1541.o drv/drv1541.cfg $(DEPS) $(LD) -C drv/drv1541.cfg $(BUILD_DIR)/drv/drv1541.o -o $@ +$(BUILD_DIR)/drv/drv1541parallel.bin: $(BUILD_DIR)/drv/drv1541parallel.o drv/drv1541parallel.cfg $(DEPS) + $(LD) -C drv/drv1541parallel.cfg $(BUILD_DIR)/drv/drv1541parallel.o -o $@ + $(BUILD_DIR)/drv/drv1571.bin: $(BUILD_DIR)/drv/drv1571.o drv/drv1571.cfg $(DEPS) $(LD) -C drv/drv1571.cfg $(BUILD_DIR)/drv/drv1571.o -o $@ diff --git a/config.inc b/config.inc index eca79b6a..b028f71f 100755 --- a/config.inc +++ b/config.inc @@ -168,6 +168,8 @@ REUPresent = 1 .if .defined(drv1541) DRV_TYPE = 1 ; DRV_1541 +.elseif .defined(drv1541parallel) +DRV_TYPE = 1; DRV_1541 .elseif .defined(drv1571) DRV_TYPE = 2; DRV_1571 .elseif .defined(drv1581) diff --git a/drv/drv1541parallel.cfg b/drv/drv1541parallel.cfg new file mode 100644 index 00000000..25d05603 --- /dev/null +++ b/drv/drv1541parallel.cfg @@ -0,0 +1,11 @@ +MEMORY { + DISK_BASE: start = $9000, size = $0D80, file = %O; + + DRIVE0300: start = $0300, size = $0500; +} + +SEGMENTS { + drv1541: load = DISK_BASE, type = ro; + drv1541_drivecode: load = DISK_BASE, run = DRIVE0300, type = ro; + drv1541_b: load = DISK_BASE, type = ro; +} diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s new file mode 100644 index 00000000..023dcf12 --- /dev/null +++ b/drv/drv1541parallel.s @@ -0,0 +1,1552 @@ +; GEOS by Berkeley Softworks +; reverse engineered by Maciej Witkowiak, Michael Steil +; +; Commodore 1541 disk driver with parallel cable + +.include "const.inc" +.include "geossym.inc" +.include "geosmac.inc" +.include "config.inc" +.include "kernal.inc" +.include "jumptab.inc" +.include "c64.inc" + +.segment "drv1541" + +DriveAddy = $0300 + +_InitForIO: + .word __InitForIO +_DoneWithIO: + .word __DoneWithIO +_ExitTurbo: + .word __ExitTurbo +_PurgeTurbo: + .word __PurgeTurbo +_EnterTurbo: + .word __EnterTurbo +_ChangeDiskDevice: + .word __ChangeDiskDevice +_NewDisk: + .word __NewDisk +_ReadBlock: + .word __ReadBlock +_WriteBlock: + .word __WriteBlock +_VerWriteBlock: + .word __VerWriteBlock +_OpenDisk: + .word __OpenDisk +_GetBlock: + .word __GetBlock +_PutBlock: + .word __PutBlock +_GetDirHead: + .word __GetDirHead +_PutDirHead: + .word __PutDirHead +_GetFreeDirBlk: + .word __GetFreeDirBlk +_CalcBlksFree: + .word __CalcBlksFree +_FreeBlock: + .word __FreeBlock +_SetNextFree: + .word __SetNextFree +_FindBAMBit: + .word __FindBAMBit +_NxtBlkAlloc: + .word __NxtBlkAlloc +_BlkAlloc: + .word __BlkAlloc +_ChkDkGEOS: + .word __ChkDkGEOS +_SetGEOSDisk: + .word __SetGEOSDisk + +Get1stDirEntry: + jmp _Get1stDirEntry +GetNxtDirEntry: + jmp _GetNxtDirEntry +GetBorder: + jmp _GetBorder +AddDirBlock: + jmp _AddDirBlock +ReadBuff: + jmp _ReadBuff +WriteBuff: + jmp _WriteBuff + jmp DUNK4_2 + jmp GetDOSError +AllocateBlock: + jmp _AllocateBlock +ReadLink: + jmp _ReadLink + +__GetDirHead: + jsr SetDirHead + bne __GetBlock +_ReadBuff: + LoadW r4, diskBlkBuf +__GetBlock: + jsr EnterTurbo + bnex GetBlk0 + jsr InitForIO + jsr ReadBlock + jsr DoneWithIO +GetBlk0: + rts + +__PutDirHead: + jsr SetDirHead + bne __PutBlock +_WriteBuff: + LoadW r4, diskBlkBuf +__PutBlock: + jsr EnterTurbo + bnex PutBlk1 + jsr InitForIO + jsr WriteBlock + bnex PutBlk0 + jsr VerWriteBlock +PutBlk0: + jsr DoneWithIO +PutBlk1: + rts + +SetDirHead: + LoadB r1L, DIR_TRACK + LoadB r1H, 0 + sta r4L + LoadB r4H, (>curDirHead) + rts + +CheckParams: + bbrf 6, curType, CheckParams_1 + jsr DoCacheVerify + beq CheckParams_2 +CheckParams_1: + lda #0 + sta errCount + ldx #INV_TRACK + lda r1L + beq CheckParams_2 + cmp #N_TRACKS+1 + bcs CheckParams_2 + sec + rts +CheckParams_2: + clc + rts + +__OpenDisk: + ldy curDrive + lda _driveType,y + sta tmpDriveType + and #%10111111 + sta _driveType,y + jsr NewDisk + bnex OpenDsk1 + jsr GetDirHead + bnex OpenDsk1 + bbrf 6, tmpDriveType, OpenDsk0 + jsr DoCacheVerify + beq OpenDsk0 + jsr DoClearCache + jsr SetDirHead + jsr DoCacheWrite +OpenDsk0: + LoadW r5, curDirHead + jsr ChkDkGEOS + LoadW r4, curDirHead+OFF_DISK_NAME + ldx #r5 + jsr GetPtrCurDkNm + ldx #r4 + ldy #r5 + lda #18 + jsr CopyFString + ldx #0 +OpenDsk1: + lda tmpDriveType + ldy curDrive + sta _driveType,y + rts +tmpDriveType: + .byte 0 + +__BlkAlloc: + ldy #1 + sty r3L + dey + sty r3H +__NxtBlkAlloc: + PushW r9 + PushW r3 + LoadW r3, $00fe + ldx #r2 + ldy #r3 + jsr Ddiv + lda r8L + beq BlkAlc0 + inc r2L + bne BlkAlc0 + inc r2H +BlkAlc0: + LoadW r5, curDirHead + jsr CalcBlksFree + PopW r3 + ldx #INSUFF_SPACE + CmpW r2, r4 + beq BlkAlc1 + bcs BlkAlc4 +BlkAlc1: + MoveW r6, r4 + MoveW r2, r5 +BlkAlc2: + jsr SetNextFree + bnex BlkAlc4 + ldy #0 + lda r3L + sta (r4),y + iny + lda r3H + sta (r4),y + AddVW 2, r4 + lda r5L + bne @X + dec r5H +@X: dec r5L + lda r5L + ora r5H + bne BlkAlc2 + ldy #0 + tya + sta (r4),y + iny + lda r8L + bne BlkAlc3 + lda #$fe +BlkAlc3: + clc + adc #1 + sta (r4),y + ldx #0 +BlkAlc4: + PopW r9 + rts + +_Get1stDirEntry: + LoadB r1L, DIR_TRACK + LoadB r1H, 1 + jsr ReadBuff + LoadW r5, diskBlkBuf+FRST_FILE_ENTRY + lda #0 + sta borderFlag + rts + +_GetNxtDirEntry: + ldx #0 + ldy #0 + AddVW $20, r5 + CmpWI r5, diskBlkBuf+$ff + bcc GNDirEntry1 + ldy #$ff + MoveW diskBlkBuf, r1 + bne GNDirEntry0 + lda borderFlag + bne GNDirEntry1 + lda #$ff + sta borderFlag + jsr GetBorder + bnex GNDirEntry1 + tya + bne GNDirEntry1 +GNDirEntry0: + jsr ReadBuff + ldy #0 + LoadW r5, diskBlkBuf+FRST_FILE_ENTRY +GNDirEntry1: + rts + +_GetBorder: + jsr GetDirHead + bnex GetBord2 + LoadW r5, curDirHead + jsr ChkDkGEOS + bne GetBord0 + ldy #$ff + bne GetBord1 +GetBord0: + MoveW curDirHead+OFF_OP_TR_SC, r1 + ldy #0 +GetBord1: + ldx #0 +GetBord2: + rts + +__ChkDkGEOS: + ldy #OFF_GS_ID + ldx #0 + LoadB isGEOS, 0 +ChkDkG0: + lda (r5),y + cmp GEOSDiskID,x + bne ChkDkG1 + iny + inx + cpx #11 + bne ChkDkG0 + LoadB isGEOS, $ff +ChkDkG1: + lda isGEOS + rts + +GEOSDiskID: + .byte "GEOS format V1.0",NULL + +__GetFreeDirBlk: + php + sei + PushB r6L + PushW r2 + ldx r10L + inx + stx r6L + LoadB r1L, DIR_TRACK + LoadB r1H, 1 +GFDirBlk0: + jsr ReadBuff +GFDirBlk1: + bnex GFDirBlk5 + dec r6L + beq GFDirBlk3 +GFDirBlk11: + lda diskBlkBuf + bne GFDirBlk2 + jsr AddDirBlock + bra GFDirBlk1 +GFDirBlk2: + sta r1L + MoveB diskBlkBuf+1, r1H + bra GFDirBlk0 +GFDirBlk3: + ldy #FRST_FILE_ENTRY + ldx #0 +GFDirBlk4: + lda diskBlkBuf,y + beq GFDirBlk5 + tya + addv $20 + tay + bcc GFDirBlk4 + LoadB r6L, 1 + ldx #FULL_DIRECTORY + ldy r10L + iny + sty r10L + cpy #$12 + bcc GFDirBlk11 +GFDirBlk5: + PopW r2 + PopB r6L + plp + rts + +_AddDirBlock: + PushW r6 + ldy #$48 + ldx #FULL_DIRECTORY + lda curDirHead,y + beq ADirBlk0 + MoveW r1, r3 + jsr SetNextFree + MoveW r3, diskBlkBuf + jsr WriteBuff + bnex ADirBlk0 + MoveW r3, r1 + jsr ClearAndWrite +ADirBlk0: + PopW r6 + rts + +ClearAndWrite: + lda #0 + tay +CAndWr0: + sta diskBlkBuf,y + iny + bne CAndWr0 + dey + sty diskBlkBuf+1 + jmp WriteBuff + +__SetNextFree: + lda r3H + add interleave + sta r6H + MoveB r3L, r6L + cmp #25 + bcc SNxtFree0 + dec r6H +SNxtFree0: + cmp #DIR_TRACK + beq SNxtFree1 +SNxtFree00: + lda r6L + cmp #DIR_TRACK + beq SNxtFree3 +SNxtFree1: + asl + asl + tax + lda curDirHead,x + beq SNxtFree3 + lda r6L + jsr SNxtFreeHelp + lda SecScTab,x + sta r7L + tay +SNxtFree2: + jsr SNxtFreeHelp2 + beq SNxtFree4 + inc r6H + dey + bne SNxtFree2 +SNxtFree3: + inc r6L + CmpBI r6L, N_TRACKS+1 + bcs SNxtFree5 + sub r3L + sta r6H + asl + adc #4 + adc interleave + sta r6H + bra SNxtFree00 +SNxtFree4: + MoveW_ r6, r3 + ldx #0 + rts +SNxtFree5: + ldx #INSUFF_SPACE + rts + +SNxtFreeHelp: + ldx #0 +SNFHlp0: + cmp SecTrTab,x + bcc SNFHlp1 + inx + bne SNFHlp0 +SNFHlp1: + rts + +SecTrTab: + .byte 18, 25, 31, 36 +SecScTab: + .byte 21, 19, 18, 17 + +SNxtFreeHelp2: + lda r6H +SNFHlp2_1: + cmp r7L + bcc SNFHlp2_2 + sub r7L + bra SNFHlp2_1 +SNFHlp2_2: + sta r6H + +_AllocateBlock: + jsr FindBAMBit + beq SNFHlp2_3 + lda r8H + eor #$ff + and curDirHead,x + sta curDirHead,x + ldx r7H + dec curDirHead,x + ldx #0 + rts +SNFHlp2_3: + ldx #BAD_BAM + rts + +__FindBAMBit: + lda r6L + asl + asl + sta r7H + lda r6H + and #%00000111 + tax + lda FBBBitTab,x + sta r8H + lda r6H + lsr + lsr + lsr + sec + adc r7H + tax + lda curDirHead,x + and r8H + rts + +FBBBitTab: + .byte $01, $02, $04, $08 + .byte $10, $20, $40, $80 + +__FreeBlock: + jsr FindBAMBit + bne FreeBlk0 + lda r8H + eor curDirHead,x + sta curDirHead,x + ldx r7H + inc curDirHead,x + ldx #0 + rts +FreeBlk0: + ldx #BAD_BAM + rts + +__CalcBlksFree: + LoadW_ r4, 0 + ldy #OFF_TO_BAM +CBlksFre0: + lda (r5),y + add r4L + sta r4L + bcc CBlksFre1 + inc r4H +CBlksFre1: + tya + clc + adc #4 + tay + cpy #$48 + beq CBlksFre1 + cpy #$90 + bne CBlksFre0 + LoadW r3, $0298 + rts + +__SetGEOSDisk: + jsr GetDirHead + bnex SetGDisk2 + LoadW r5, curDirHead + jsr CalcBlksFree + ldx #INSUFF_SPACE + lda r4L + ora r4H + beq SetGDisk2 + LoadB r3L, DIR_TRACK+1 + LoadB r3H, 0 + jsr SetNextFree + beqx SetGDisk0 + LoadB r3L, 1 + jsr SetNextFree + bnex SetGDisk2 +SetGDisk0: + MoveW r3, r1 + jsr ClearAndWrite + bnex SetGDisk2 + MoveW r1, curDirHead+OFF_OP_TR_SC + ldy #OFF_GS_ID+15 + ldx #15 +SetGDisk1: + lda GEOSDiskID,x + sta curDirHead,y + dey + dex + bpl SetGDisk1 + jsr PutDirHead +SetGDisk2: + rts + +__InitForIO: + php + PopB tmpPS + sei + MoveB CPU_DATA, tmpCPU_DATA +.ifndef bsw128 + LoadB CPU_DATA, KRNL_IO_IN +.endif + MoveB grirqen, tmpgrirqen + MoveB clkreg, tmpclkreg + ldy #0 + sty clkreg + sty grirqen + lda #%01111111 + sta grirq + sta cia1base+13 + sta cia2base+13 + lda #>D_IRQHandler + sta irqvec+1 +.ifdef bsw128 + sta nmivec+1 +.endif + lda #D_NMIHandler + sta nmivec+1 + lda #DExeProc + sta z8c + lda #EnterCommand + lda #Drv_ExitTurbo + lda #DriveCode + sta z8e + lda #DriveAddy + sta WriteAddy+1 + lda #WriteCommand + lda #Drv_NewDisk + sta z8c + lda #Drv_ChngDskDev + lda #Drv_ReadSec + lda #Drv_SendByte + lda #Drv_WriteSec + lda #Drv_ReadSec + lda #Drv_SendByte_0 + lda #errStore + sta z8c + lda #(DriveLoop-1) ; return address + pha + lda #<(DriveLoop-1) + pha + jmp (DExecAddy) + +Drv_ExitTurbo: + jsr D_DUNK4_1 + LoadB $33, 0 + sta $1800 + jsr $f98f ; turn drive motor off + LoadB $1c0c, $ec + pla + pla + PopB $49 + plp + rts + +Drv_ChngDskDev: + lda DDatas + sta $77 + eor #$60 + sta $78 + rts + +D_DUNK5: + jsr D_DUNK12 + lda $22 + beq D_DUNK5_1 + ldx $00 + dex + beq D_DUNK5_2 +D_DUNK5_1: + PushB $12 + PushB $13 + jsr Drv_NewDisk_1 + PopB $13 + tax + PopB $12 + ldy $00 + cpy #$01 + bne D_DUNK5_41 + cpx $17 + bne D_DUNK5_5 + cmp $16 + bne D_DUNK5_5 + lda #0 +D_DUNK5_2: + pha + lda $22 + ldx #$ff + sec + sbc DDatas + beq D_DUNK5_4 + bcs D_DUNK5_3 + eor #$ff + adc #1 + ldx #1 +D_DUNK5_3: + jsr D_DUNK6 + lda DDatas + sta $22 + jsr Drv_NewDisk_6 +D_DUNK5_4: + pla +D_DUNK5_41: + rts +D_DUNK5_5: + LoadB $00, $0b + rts + +D_DUNK6: + stx $4a + asl + tay + lda $1c00 + and #$fe + sta $70 + lda #$1e + sta $71 +D_DUNK6_1: + lda $70 + add $4a + eor $70 + and #%00000011 + eor $70 + sta $70 + sta $1c00 + lda $71 + jsr D_DUNK6_4 + lda $71 + cpy #5 + bcc D_DUNK6_2 + cmp #$11 + bcc D_DUNK6_3 + sbc #2 + bne D_DUNK6_3 +D_DUNK6_2: + cmp #$1c + bcs D_DUNK6_3 + adc #4 +D_DUNK6_3: + sta $71 + dey + bne D_DUNK6_1 + lda #$4b +D_DUNK6_4: + sta $1805 + lda $1805 + bne *-3 + rts + +Drv_NewDisk: + jsr D_DUNK12 +Drv_NewDisk_1: + ldx $00 + dex + beq Drv_NewDisk_2 + ldx #$ff + lda #$01 + jsr D_DUNK6 + ldx #$01 + txa + jsr D_DUNK6 + lda #$ff + jsr D_DUNK6_4 +Drv_NewDisk_2: + LoadB $70, $04 +Drv_NewDisk_3: + jsr D_DUNK11 + ldx $18 + stx $22 + ldy $00 + dey + beq Drv_NewDisk_5 + dec $70 + bmi Drv_NewDisk_4 + ldx $70 + jsr Drv_NewDisk_7 + sec + bcs Drv_NewDisk_3 +Drv_NewDisk_4: + LoadB $22, 0 + rts +Drv_NewDisk_5: + txa +Drv_NewDisk_6: + jsr $f24b ; Establish number of sectors per track (in: A=track, out: A=number of sectors on that track) + sta $43 +Drv_NewDisk_7: + lda $1c00 + and #$9f + ora DTrackTab,x +Drv_NewDisk_8: + sta $1c00 + rts + +D_DUNK8: ; LED off? + lda #$f7 + bne D_DUNK8_3 +D_DUNK8_1: ; LED on? + lda #$08 + ora $1c00 + bne Drv_NewDisk_8 + +D_DUNK8_2: + LoadB $20, 0 + LoadB $3e, $ff + lda #$fb +D_DUNK8_3: + and $1c00 + jmp Drv_NewDisk_8 + +DTrackTab: + .byte $00, $20, $40, $60 + +D_DUNK9: + tax + bbrf 7, $20, D_DUNK9_0 + jsr D_DUNK12_1 + LoadB $20, $20 + ldx #0 +D_DUNK9_0: + cpx $22 + beq D_DUNK9_1 + jsr Drv_NewDisk_2 + cmp #1 + bne D_DUNK9_1 + ldy $19 + iny + cpy $43 + bcc @X + ldy #0 +@X: sty $19 + LoadB $45, 0 + LoadW $32, $0018 + jsr D_DUNK11_1 +D_DUNK9_1: + rts + +Drv_WriteSec: + jsr D_DUNK5 + ldx $00 + dex + bne D_DUNK10_1 + jsr D_DUNK9 +D_DUNK10_1: + jsr Drv_RecvWord + lda #$10 + bne D_DUNK10_2 +Drv_ReadSec: + jsr D_DUNK5 + lda #0 +D_DUNK10_2: + ldx $00 + dex + beq D_DUNK11_0 + rts + +D_DUNK11: + lda #$30 +D_DUNK11_0: + sta $45 + lda #>DDatas + sta $33 + lda # Date: Sat, 23 Mar 2024 12:21:24 +0100 Subject: [PATCH 03/27] optimizations --- drv/drv1541parallel.s | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 023dcf12..b6e92e77 100644 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -633,13 +633,12 @@ __DoneWithIO: rts Hst_RecvByte: -Hst_RecvByte_0: : lda cia2base+13 ; wait for flag beq :- lda cia2base+1 ; read data dey sta (z8b),y - bne Hst_RecvByte_0 + bne :- rts Hst_SendByte: @@ -1034,12 +1033,8 @@ Drv_SendByte_0: ldy #0 sty $73 sty $74 - iny - sty $71 - ldy #0 - lda $71 jsr Drv_SendByte_1 - ldy $71 + ldy #1 Drv_SendByte_1: LoadB $1803, $ff ; port A output Drv_SendByte_2: From 212c42b537053a21fd3fe5f4ad41c78aeb15cc86 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sat, 23 Mar 2024 12:50:38 +0100 Subject: [PATCH 04/27] maximum drive code size is -bash400 (-bash300--bash6ff), calculate on the fly number of 32-byte (0) chunks needed to be sent via memory-write --- drv/drv1541parallel.cfg | 4 ++-- drv/drv1541parallel.s | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drv/drv1541parallel.cfg b/drv/drv1541parallel.cfg index 25d05603..bc204c46 100644 --- a/drv/drv1541parallel.cfg +++ b/drv/drv1541parallel.cfg @@ -1,11 +1,11 @@ MEMORY { DISK_BASE: start = $9000, size = $0D80, file = %O; - DRIVE0300: start = $0300, size = $0500; + DRIVE0300: start = $0300, size = $0400; } SEGMENTS { drv1541: load = DISK_BASE, type = ro; - drv1541_drivecode: load = DISK_BASE, run = DRIVE0300, type = ro; + drv1541_drivecode: load = DISK_BASE, run = DRIVE0300, type = ro, define = yes; drv1541_b: load = DISK_BASE, type = ro; } diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index b6e92e77..175d4778 100644 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -11,9 +11,10 @@ .include "jumptab.inc" .include "c64.inc" -.segment "drv1541" +.import __drv1541_drivecode_RUN__ +.import __drv1541_drivecode_SIZE__ -DriveAddy = $0300 +.segment "drv1541" _InitForIO: .word __InitForIO @@ -776,15 +777,9 @@ SendExitTurbo: SendCODE: jsr InitForIO - lda #>DriveCode - sta z8e - lda #DriveAddy - sta WriteAddy+1 - lda # Date: Sat, 23 Mar 2024 14:14:00 +0100 Subject: [PATCH 05/27] more macros and comments --- drv/drv1541parallel.s | 49 +++++++++++++------------------------------ 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 175d4778..cc6c8d1e 100644 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -688,32 +688,23 @@ SndDOSCmd1: ldx #DEV_NOT_FOUND rts -DUNK4: +DUNK4: ; A/X addr of procedure to run, without parameters stx z8c sta z8b - ldy #2 + ldy #2 ; 2 bytes to send bne DUNK4_3 -DUNK4_1: +DUNK4_1: ; A/X addr of procedure to run, r1 t&s parameters stx z8c sta z8b -DUNK4_2: - ldy #4 - lda r1H - sta DTrkSec+1 - lda r1L - sta DTrkSec +DUNK4_2: ; called by NewDisk, but why send r1? + ldy #4 ; 4 bytes to send + MoveW r1, DTrkSec DUNK4_3: - lda z8c - sta DExeProc+1 - lda z8b - sta DExeProc - lda #>DExeProc - sta z8c - lda #Drv_NewDisk - sta z8c - lda #errStore - sta z8c - lda # Date: Sat, 23 Mar 2024 14:33:47 +0100 Subject: [PATCH 06/27] improve parallelism a bit --- drv/drv1541parallel.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index cc6c8d1e..346c2e82 100644 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1042,8 +1042,8 @@ Drv_RecvByte_1: lda #$10 : bit $180d beq :- - bit $1800 ; clear CB1 lda $1801 ; read data + bit $1800 ; clear CB1 dey sta ($73),y bne Drv_RecvByte_1 From 54cef0285a6a1b835469770530e221008733170d Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Mon, 25 Mar 2024 21:16:20 +0100 Subject: [PATCH 07/27] fix Drv_SendByte_0 to send exactly two bytes as status: length (1) and content (value from -bash0) --- drv/drv1541parallel.s | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) mode change 100644 => 100755 drv/drv1541parallel.s diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s old mode 100644 new mode 100755 index 346c2e82..09d11024 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1008,11 +1008,19 @@ Drv_SendByte: ldy #0 jsr Drv_SendByte_1 Drv_SendByte_0: - ldy #0 - sty $73 - sty $74 - jsr Drv_SendByte_1 - ldy #1 + LoadB $1803, $ff + LoadB $1801, $01 + lda #$10 +: bit $180d + beq :- + bit $1800 + ldy $00 + sty $1801 +: bit $180d + beq :- + bit $1800 + LoadB $1803, $00 + rts Drv_SendByte_1: LoadB $1803, $ff ; port A output Drv_SendByte_2: From c9c974a9a081b7a6db185d4e3b9bf0348d10f3bf Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Mon, 25 Mar 2024 21:53:47 +0100 Subject: [PATCH 08/27] optimized drive->host transfer procedure from 35 cycles down to 27/28 --- drv/drv1541parallel.s | 63 ++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 09d11024..e51c8f7a 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -634,12 +634,18 @@ __DoneWithIO: rts Hst_RecvByte: + MoveW z8b, RecvAddr +: nop ; delay adjusted to Drv_SendByte timing + nop ; so that branch after wait for flag is mostly not taken + nop ; (4xNOP)=28 cycles per byte loop + nop : lda cia2base+13 ; wait for flag beq :- lda cia2base+1 ; read data dey - sta (z8b),y - bne :- +RecvAddr = *+1 + sta $8000,y + bne :-- rts Hst_SendByte: @@ -1002,40 +1008,49 @@ DOSErrTab: DriveCode: .segment "drv1541_drivecode" -; .org DriveAddy -Drv_SendByte: +Drv_SendByte: ; send 256 bytes, then length (1) and status byte from $00 ldy #0 - jsr Drv_SendByte_1 -Drv_SendByte_0: - LoadB $1803, $ff - LoadB $1801, $01 - lda #$10 -: bit $180d - beq :- - bit $1800 - ldy $00 - sty $1801 -: bit $180d - beq :- - bit $1800 - LoadB $1803, $00 - rts + MoveW $73, Drv_SendAddr Drv_SendByte_1: LoadB $1803, $ff ; port A output -Drv_SendByte_2: - dey + dey ; first byte lda ($73),y - sta $1801 ; send data + sta $1801 ; send first byte + lda #$10 ; bit mask for handshake test +Drv_SendByte_2: ; 27 cycles per byte + cpy #0 + beq Drv_SendByteEnd + dey +: bit $180d ; wait for handshake + beq :- +Drv_SendAddr = *+1 + ldx $0700,y ; 1 cycle faster than lda ($73),y and we can keep A unchanged for bit test + stx $1801 ; send data + bit $1800 ; clear flag from previous handshake + jmp Drv_SendByte_2 + +Drv_SendByteEnd: +: bit $180d ; wait for handshake + beq :- + bit $1800 ; clear flag + +Drv_SendByte_0: + LoadB $1803, $ff ; send length (1) and status byte from $00 + LoadB $1801, $01 ; send length lda #$10 : bit $180d ; wait for handshake beq :- bit $1800 ; clear flag - cpy #0 - bne Drv_SendByte_2 + ldy $00 + sty $1801 ; send status +: bit $180d ; wait for handshake + beq :- + bit $1800 ; clear flag LoadB $1803, $00 ; port A input rts + Drv_RecvWord: ldy #1 jsr Drv_RecvByte From 6e20babf7f33dbb19b867addea87a0064fd834c4 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Mon, 25 Mar 2024 21:57:22 +0100 Subject: [PATCH 09/27] remarks and optimal interleave setting --- drv/drv1541parallel.s | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index e51c8f7a..458e91f6 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1,7 +1,9 @@ ; GEOS by Berkeley Softworks ; reverse engineered by Maciej Witkowiak, Michael Steil ; -; Commodore 1541 disk driver with parallel cable +; Commodore 1541 disk driver with parallel cable by Maciej Witkowiak +; NOTE: OPTIMAL_INTERLEAVE has to be determined experimentally +; NOTE2: if drive code jams - check if 'jmp (DExecAddy)' is on page boundary - it's dangerously close .include "const.inc" .include "geossym.inc" @@ -14,6 +16,9 @@ .import __drv1541_drivecode_RUN__ .import __drv1541_drivecode_SIZE__ +; we send data about 2,5 times faster, so it must be smaller than 8 +OPTIMAL_INTERLEAVE = 8 + .segment "drv1541" _InitForIO: @@ -721,6 +726,7 @@ DUNK5: ; receive 2 bytes, but ignorethe first(?) rts __EnterTurbo: + LoadB interleave, OPTIMAL_INTERLEAVE lda curDrive jsr SetDevice ldx curDrive From 794c87d37a9450513d798ef07ccf8334d55f126e Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Mon, 25 Mar 2024 22:55:43 +0100 Subject: [PATCH 10/27] updated with drv1541parallel mentions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6536e78f..e3fd1455 100755 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Without pucrunch/c1541, you can still build an uncompressed KERNAL binary image. Run `make` to build the original "BSW" GEOS for C64. This will create the following files in directory `build/bsw`: * raw KERNAL components: `kernal.bin`, `lokernal.bin`, `init.bin` -* disk drive drivers: `drv1541.bin`, `drv1571.bin`, `drv1581.bin` +* disk drive drivers: `drv1541.bin`, `drv1541parallel.bin`, `drv1571.bin`, `drv1581.bin` * input drivers: `amigamse.bin`, `joydrv.bin`, `lightpen.bin`, `mse1351.bin`, `koalapad.bin`, `pcanalog.bin` * combined KERNAL image (`SYS 49155`): `kernal_combined.prg` * compressed KERNAL image (`RUN`): `kernal_compressed.prg` @@ -112,7 +112,7 @@ By default, the KERNAL image will contain the Commodore 1541 disk driver (`drv15 make DRIVE= INPUT= -Supported drives are `drv1541`, `drv1571` and `drv1581`. Supported input devices are `amigamse`, `joydrv`, `koalapad`, `lightpen`, `mse1351` and `pcanalog`. +Supported drives are `drv1541`, `drv1541parallel`, `drv1571` and `drv1581`. Supported input devices are `amigamse`, `joydrv`, `koalapad`, `lightpen`, `mse1351` and `pcanalog`. ## Customization From 448e0c2a12d229ee21a48fef610ed243dc77d66c Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sat, 30 Mar 2024 20:56:02 +0100 Subject: [PATCH 11/27] found that 6 is the optimum interleave value --- drv/drv1541parallel.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 458e91f6..c42d0e98 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -16,8 +16,7 @@ .import __drv1541_drivecode_RUN__ .import __drv1541_drivecode_SIZE__ -; we send data about 2,5 times faster, so it must be smaller than 8 -OPTIMAL_INTERLEAVE = 8 +OPTIMAL_INTERLEAVE = 6 ; 6 gives a 22% speedup .segment "drv1541" From b42dc4d40707deaf6ac547d3bfaeac6b0267dd05 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sat, 30 Mar 2024 19:16:17 +0100 Subject: [PATCH 12/27] parallel version with otf-gcr decoding but will crash on write --- Makefile | 4 +- drv/drv1541parallel.cfg | 4 +- drv/drv1541parallel.s | 283 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 277 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 6c918043..f1da873d 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ else D64_TEMPLATE = GEOS64.D64 endif -ASFLAGS = -I inc -I . +ASFLAGS = -I inc -I . --cpu 6502X # code that is in front bank of all variants KERNAL_SOURCES= \ @@ -382,7 +382,7 @@ $(BUILD_DIR)/drv/drv1541.bin: $(BUILD_DIR)/drv/drv1541.o drv/drv1541.cfg $(DEPS) $(LD) -C drv/drv1541.cfg $(BUILD_DIR)/drv/drv1541.o -o $@ $(BUILD_DIR)/drv/drv1541parallel.bin: $(BUILD_DIR)/drv/drv1541parallel.o drv/drv1541parallel.cfg $(DEPS) - $(LD) -C drv/drv1541parallel.cfg $(BUILD_DIR)/drv/drv1541parallel.o -o $@ + $(LD) -C drv/drv1541parallel.cfg -m $(BUILD_DIR)/drv/drv1541parallel.map $(BUILD_DIR)/drv/drv1541parallel.o -o $@ $(BUILD_DIR)/drv/drv1571.bin: $(BUILD_DIR)/drv/drv1571.o drv/drv1571.cfg $(DEPS) $(LD) -C drv/drv1571.cfg $(BUILD_DIR)/drv/drv1571.o -o $@ diff --git a/drv/drv1541parallel.cfg b/drv/drv1541parallel.cfg index bc204c46..d24cfb28 100644 --- a/drv/drv1541parallel.cfg +++ b/drv/drv1541parallel.cfg @@ -1,11 +1,13 @@ MEMORY { DISK_BASE: start = $9000, size = $0D80, file = %O; - DRIVE0300: start = $0300, size = $0400; + DRIVE0300: start = $0300, size = $0500, define = yes; + DRIVE0060: start = $0086, size = $70; } SEGMENTS { drv1541: load = DISK_BASE, type = ro; drv1541_drivecode: load = DISK_BASE, run = DRIVE0300, type = ro, define = yes; + drv1541_zp: load = DISK_BASE, run = DRIVE0060, type = ro, define = yes; drv1541_b: load = DISK_BASE, type = ro; } diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index c42d0e98..016851e2 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -13,8 +13,14 @@ .include "jumptab.inc" .include "c64.inc" +.import __DRIVE0300_START__ + .import __drv1541_drivecode_RUN__ .import __drv1541_drivecode_SIZE__ +.import __drv1541_zp_RUN__ +.import __drv1541_zp_LOAD__ +.import __drv1541_zp_SIZE__ + OPTIMAL_INTERLEAVE = 6 ; 6 gives a 22% speedup @@ -745,9 +751,9 @@ EntTur0: jsr SendDOSCmd bnex EntTur4 jsr $ffae + sei : lda cia2base+13 ; wait for initial sync beq :- - sei jsr DoneWithIO ldx curDrive lda _turboFlags,x @@ -780,8 +786,8 @@ SendExitTurbo: SendCODE: jsr InitForIO LoadW z8d, DriveCode - LoadW WriteAddy, __drv1541_drivecode_RUN__ - LoadB z8f, (<(__drv1541_drivecode_SIZE__ / $0020)) + LoadW WriteAddy, __DRIVE0300_START__ + LoadB z8f, (<((__drv1541_drivecode_SIZE__) / $0020)) SndCDE0: jsr SendCHUNK bnex SndCDE1 @@ -910,12 +916,15 @@ _ReadLink: jsr DoCacheRead bne RdBlock2 RdBlock0: + ldx #>Drv_RecvZP + lda #Drv_ReadSec lda #Drv_SendByte - lda # carry + sta first_mod3+1 + + bvc * + lax $1c01 ; 0 1 2 3 ddddeeee + .byt $6b,$f0 ; 4 5 arr imm, ddddd000 + clv ; 6 7 + tay ; 8 9 +first_mod3: lda gcrdecode ; 10 11 12 13 lsb = 000ccccc + ora gcrdecode+1,y ; 14 15 16 17 y = ddddd000, lsb = 00000001 + pha ; 18 19 20 first byte to $100 + + ; get sector number from the lowest 5 bits of the first byte + + and #$1f ; 21 22 + tay ; 23 24 + nop ; lda interested,y ; 25 26 + nop ; lda interested,y ; 27 28 + nop ; beq notint (not taken) ; 29 30 + ;lda interested,y ; 25 26 27 28 +;mod_safety: + ;beq notint ; 29 30 + + jmp zpc_entry ; 31 32 33 x = ----eeee +zp_return: + .byt $6b,$f0 ; arr imm, ddddd000 + tay + lda gcrdecode,x ; x = 000ccccc + ora gcrdecode+1,y ; y = ddddd000, lsb = 00000001 + + sta $24 ; checksum + + ; send out data, compute checksum + ldy #$ff + sty $1803 ; port B output + iny + sty $25 ; clear computed checksum +: pla + sta $1801 ; send next byte (reversed order, as host expects) + eor $25 + sta $25 ; update checksum + lda #$10 ; handshake test bit pattern +: bit $180d ; wait for handshake + beq :- + bit $1800 ; clear CB1 flag + dey + cpy #0 + bne :-- + + ; compare checksum ($24==$25) + CmpB $24, $25 + beq :+ + LoadB $00, 5 ; checksum error + ; if header was found in time and checksum is OK then send status byte==1 + ; if header not found, send error $04 +: jsr Drv_SendStatus + + ; restore stack + ldx #$45 + txs + + ; restore zp + +; ldx #0 +;: lda $0700,x +;;XXX sta z:<__drv1541_zp_RUN__,x +; inx +; cpx #<__drv1541_zp_SIZE__ +; bne :- + + ; return to main loop (XXX ExitTurbo must warm reset drive somehow) + jmp DriveLoop + +;FastReadZp: +.segment "drv1541" +Drv_ZPCode: +.segment "drv1541_zp" : zeropage + +prof_zp: +zpc_loop: + ; This nop is needed for the slow bitrates (at least for 00), + ; because apparently the third byte after a bvc sync might not be + ; ready at cycle 65 after all. + + ; However, with the nop, the best case time for the entire loop + ; is 128 cycles, which leaves too little slack for motor speed + ; variance at bitrate 11. + + ; Thus, we modify the bne instruction at the end of the loop to + ; either include or skip the nop depending on the current + ; bitrate. + + nop + + lax $1c01 ; 62 63 64 65 ddddeeee + .byte $6b,$f0 ; 66 67 arr imm, ddddd000 + clv ; 68 69 + tay ; 70 71 +zpc_mod3: lda gcrdecode ; 72 73 74 75 lsb = 000ccccc + ora gcrdecode+1,y ; 76 77 78 79 y = ddddd000, lsb = 00000001 + + ; first read in [0..25] + ; second read in [32..51] + ; third read in [64..77] + ; clv in [64..77] + ; in total, 80 cycles from bvc + + bvc * ; 0 1 + + pha ; 2 3 4 second complete byte (nybbles c, d) +zpc_entry: + lda #$0f ; 5 6 + sax z:zpc_mod5+1 ; 7 8 9 + + lda $1c01 ; 10 11 12 13 efffffgg + ldx #$03 ; 14 15 + sax z:zpc_mod7+1 ; 16 17 18 + .byte $4b,$fc ; 19 20 asr imm, 0efffff0 + tay ; 21 22 + ldx #$79 ; 23 24 +zpc_mod5: lda gcrdecode,x ; 25 26 27 28 lsb = 0000eeee, x = 01111001 + eor gcrdecode+$40,y ; 29 30 31 32 y = 0efffff0, lsb = 01000000 + pha ; 33 34 35 third complete byte (nybbles e, f) + + lax $1c01 ; 36 37 38 39 ggghhhhh + clv ; 40 41 + and #$1f ; 42 43 + tay ; 44 45 + + ; first read in [0..25] + ; second read in [32..51] + ; clv in [32..51] + ; in total, 46 cycles from bvc + + bvc * ; 0 1 + + lda #$e0 ; 2 3 + .byte $cb, $00 ; sbx #0 ; 4 5 +zpc_mod7: lda gcrdecode,x ; 6 7 8 9 x = ggg00000, lsb = 000000gg + ora gcrdecode+$20,y ; 10 11 12 13 y = 000hhhhh, lsb = 00100000 + pha ; 14 15 16 fourth complete byte (nybbles g, h) + + ; start of a new 5-byte chunk + + lda $1c01 ; 17 18 19 20 aaaaabbb + ldx #$f8 ; 21 22 + sax z:zpc_mod1+1 ; 23 24 25 + and #$07 ; 26 27 + ora #$08 ; 28 29 + tay ; 30 31 + + lda $1c01 ; 32 33 34 35 bbcccccd + ldx #$c0 ; 36 37 + sax z:zpc_mod2+1 ; 38 39 40 + .byt $4b,$3f ; 41 42 asr imm, 000ccccc, d -> carry + sta z:zpc_mod3+1 ; 43 44 45 + +zpc_mod1: lda gcrdecode ; 46 47 48 49 lsb = aaaaa000 +zpc_mod2: eor gcrdecode,y ; 50 51 52 53 lsb = bb000000, y = 00001bbb + pha ; 54 55 56 first complete byte (nybbles a, b) + + tsx ; 57 58 +BNE_WITH_NOP = (zpc_loop - (* + 2)) & $ff +BNE_WITHOUT_NOP = (zpc_loop + 1 - (* + 2)) & $ff +zpc_bne: .byt $d0,BNE_WITHOUT_NOP ; 59 60 61 bne zpc_loop + + ldx z:zpc_mod3+1 ; 61 62 63 + lda $1c01 ; 64 65 66 67 ddddeeee + jmp zp_return + .segment "drv1541_b" + .ifndef dontcare +ClearCache: +DoClearCache: +DoCacheRead: +DoCacheWrite: +DoCacheVerify: + rts +.else ClrCacheDat: .word 0 @@ -1523,6 +1783,7 @@ CacheTabH: .byte $01, $01, $01, $01, $01, $01, $01, $01 .byte $01, $01, $02, $02, $02, $02, $02, $02 .byte $02, $02, $02, $02 +.endif tmpclkreg: .byte 0 From b4d92057d50934af02450095d0cc65207351de2f Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sat, 30 Mar 2024 20:10:36 +0100 Subject: [PATCH 13/27] optimal interleave --- drv/drv1541parallel.s | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 016851e2..8bfa2809 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -21,8 +21,26 @@ .import __drv1541_zp_LOAD__ .import __drv1541_zp_SIZE__ - -OPTIMAL_INTERLEAVE = 6 ; 6 gives a 22% speedup +; interleave testing in VICE (load DESK TOP saved with that interleave, count cycles between c326 and c3a8) +; interleave start end diff diff% +;1 124188392 138549570 14361178 226% +;2 206544077 221469179 14925102 235% +;3 323246805 326144363 2897558 46% +;4 377406197 380848405 3442208 54% +;5 444598875 448993889 4395014 69% +;6 503908689 508692309 4783620 75% +;7 567056391 572631055 5574664 88% +;8 630004373 636087138 6082765 96% +;9 717602340 724270720 6668380 105% +;10 779826865 787041178 7214313 113% +;11 873107683 881082247 7974564 125% +;12 924738595 933295187 8556592 135% +;13 1014288120 1023780169 9492049 149% +;14 1076008138 1085921087 9912949 156% +;15 1154807307 1165244853 10437546 164% + + +OPTIMAL_INTERLEAVE = 3 .segment "drv1541" From 53773b7e020e7f9348a8980676d3a709616bbf9d Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sun, 31 Mar 2024 18:32:43 +0200 Subject: [PATCH 14/27] working read/write version, buffer at 0x700 cached at 0x200 reloaded if needed, same with ZP code --- drv/drv1541parallel.s | 131 +++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 79 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 8bfa2809..8207e93b 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -14,6 +14,7 @@ .include "c64.inc" .import __DRIVE0300_START__ +.import __DRIVE0300_LAST__ .import __drv1541_drivecode_RUN__ .import __drv1541_drivecode_SIZE__ @@ -934,13 +935,16 @@ _ReadLink: jsr DoCacheRead bne RdBlock2 RdBlock0: + lda LastOper ; need to reload ZP code? + beq :+ ; no, it's already there + LoadB LastOper, 0 ; mark that ZP code is loaded ldx #>Drv_RecvZP lda #Drv_ReadSec +: ldx #>Drv_ReadSec ; read sector and status lda #Drv_ReadSec - lda #Drv_SendByte_0 lda # Date: Sun, 31 Mar 2024 21:05:05 +0200 Subject: [PATCH 15/27] more comments, remove dead locations and code --- drv/drv1541parallel.s | 60 ++++++++++++------------------------------- 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 8207e93b..bf09db90 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1083,7 +1083,7 @@ DriveStart: sta $180f ldx #0 stx DLastOper ; READ allowed -: lda $0700,x +: lda $0700,x ; cache code that would be in the write buffer zone sta $0200,x inx cpx #<(__DRIVE0300_LAST__-__DRIVE0300_START__) @@ -1245,10 +1245,10 @@ Drv_NewDisk_4: Drv_NewDisk_5: txa Drv_NewDisk_6: - jsr $f24b ; Establish number of sectors per track (in: A=track, out: A=number of sectors on that track) + jsr $f24b ; Establish number of sectors per track (in: A=track, out: A=number of sectors on that track, X=speed zone number) sta $43 Drv_NewDisk_7: - lda $1c00 + lda $1c00 ; set speedzone and #$9f ora DTrackTab,x Drv_NewDisk_8: @@ -1271,7 +1271,7 @@ D_DUNK8_3: and $1c00 jmp Drv_NewDisk_8 -DTrackTab: +DTrackTab: ; speedzone (bitrate) bits for $1c00 .byte $00, $20, $40, $60 D_DUNK9: @@ -1292,8 +1292,8 @@ D_DUNK9_0: bcc @X ldy #0 @X: sty $19 - LoadB $45, 0 - LoadW $32, $0018 + LoadB $45, 0 ; job READ + LoadW $32, $0018 ; sector 18,0 jsr D_DUNK11_1 D_DUNK9_1: rts @@ -1329,7 +1329,7 @@ D_DUNK10_2: rts D_DUNK11: - lda #$30 + lda #$30 ; job $B0 = SEEK D_DUNK11_0: sta $45 lda #>DDatas @@ -1347,15 +1347,14 @@ D_DUNK11_1: LoadB $1c0c, $ee lda $45 bne :+ - jmp Drv_DoReadSector -: cmp #$10 + jmp Drv_DoReadSector ; job $80 = READ +: cmp #$10 ; job $90 = WRITE bne :+ jmp Drv_DoWriteSector -: cmp #$30 - beq D_DUNK11_2 - jmp $f4ca ; Test command code further ($00=read, $10=write, $20=verify, other=read block header) -D_DUNK11_2: - jmp $f3b1 ; Read block header, verify ID +: cmp #$30 ; job $B0 = SEEK + beq :+ + jmp $f4ca ; Test command code further ($00=read, $10=write, $20=verify, $30 = SEEK, is this ever used?) +: jmp $f3b1 ; SEEK, Read block header, verify ID D_DUNK12: ; spin up motor lda $20 @@ -1433,18 +1432,6 @@ D_DUNK11_9: rts Drv_DoReadSector: - ;; -; ldx #0 -;: lda z:<__drv1541_zp_RUN__,x -;;XXX sta $0700,x -; lda FastReadZp,x -; sta z:<__drv1541_zp_RUN__,x -; inx -; cpx #<__drv1541_zp_SIZE__ -; bne :- - ;; - ;; XXX store stack - ; Encode t&s into GCR MoveW $12, $16 ; ID1,2 @@ -1552,25 +1539,13 @@ zp_return: ; if header not found, send error $04 : jsr Drv_SendStatus - ; restore stack + ; restore stack pointer (must be below $01bb) ldx #$45 txs - ; restore zp - -; ldx #0 -;: lda $0700,x -;;XXX sta z:<__drv1541_zp_RUN__,x -; inx -; cpx #<__drv1541_zp_SIZE__ -; bne :- - - ; return to main loop (XXX ExitTurbo must warm reset drive somehow) + ; return to main loop (XXX ExitTurbo must warm reset drive somehow because we have destroyed stack contents) jmp DriveLoop -;FastReadZp: -.segment "drv1541" -Drv_ZPCode: .segment "drv1541_zp" : zeropage prof_zp: @@ -1667,7 +1642,8 @@ zpc_bne: .byt $d0,BNE_WITHOUT_NOP ; 59 60 61 bne zpc_loop .segment "drv1541_b" - .ifndef dontcare +; there is no space for cache code and tables anymore with disk driver area, so no Shadow 1541 possible + .ifndef notpossible ClearCache: DoClearCache: DoCacheRead: @@ -1792,8 +1768,6 @@ errCount: .byte 0 errStore: .byte 0 -tryCount: - .byte 0 borderFlag: .byte 0 LastOper: From b6e303e2da75b90a894e0563d4a72eab6682bec9 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sun, 31 Mar 2024 21:14:11 +0200 Subject: [PATCH 16/27] faster turnaround for WriteBlock --- drv/drv1541parallel.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index bf09db90..1077ceb9 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -976,7 +976,7 @@ WrBlock1: MoveW r4, z8b ldy #0 jsr Hst_SendByte - jsr GetDOSError + jsr GetDError beq WrBlock2 inc errCount cpy errCount @@ -1429,7 +1429,7 @@ D_DUNK11_8: lda #1 D_DUNK11_9: sta $00 - rts + jmp Drv_SendByte_0 ; set port to output, send status from $00 Drv_DoReadSector: ; Encode t&s into GCR From 3c0979876fefc01f38579e0c018552b133aa4216 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sun, 31 Mar 2024 21:26:16 +0200 Subject: [PATCH 17/27] more general memory recieve routine --- drv/drv1541parallel.s | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 1077ceb9..d0997070 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -938,12 +938,15 @@ RdBlock0: lda LastOper ; need to reload ZP code? beq :+ ; no, it's already there LoadB LastOper, 0 ; mark that ZP code is loaded - ldx #>Drv_RecvZP + PushW r1 + LoadW r1, __drv1541_zp_RUN__ ; target address + ldx #>Drv_RecvZP ; recieve data lda #Drv_ReadSec ; read sector and status lda # Date: Sun, 31 Mar 2024 22:36:44 +0200 Subject: [PATCH 18/27] faster code upload (forced after every ExitTurbo), make ExitTurbo reset, we are at the size limit --- drv/drv1541parallel.s | 113 ++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 37 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index d0997070..11b9bd56 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -757,8 +757,9 @@ __EnterTurbo: lda _turboFlags,x bmi EntTur0 jsr SendCODE - bnex EntTur5 - ldx curDrive + beqx :+ + jmp EntTur5 +: ldx curDrive lda #%10000000 sta _turboFlags,x EntTur0: @@ -769,10 +770,43 @@ EntTur0: lda #DriveCode + LoadW r1, __DRIVE0300_START__ ; target address +EntTur1: + ldx #>Drv_RecvZP ; recieve data + lda #DriveCode + sta z8c + ldy #0 + jsr Hst_SendByte + inc r1H + inc EntTH+1 + CmpBI r1H, $08 + bne EntTur1 + ; send page 7 data also to page 2 + LoadB r1H, $02 + ldx #>Drv_RecvZP + lda #Drv_ReadSec ; read sector and status +: rts + +__ReadBlock: +_ReadLink: + jsr CheckParams_1 + bcc RdBlock2 + bbrf 6, curType, RdBlock0 + jsr DoCacheRead + bne RdBlock2 +RdBlock0: + jsr ReloadDrvZP + ldx #>Drv_ReadSec ; read sector and status lda #(DriveLoop-1) ; return address pha @@ -1103,11 +1139,23 @@ DriveLoop: pha jmp (DExecAddy) +Drv_LedOFF: + lda #$f7 + and $1c00 +Drv_LedDo: + sta $1c00 + rts +Drv_LedON: + lda #$08 + ora $1c00 + bne Drv_LedDo + Drv_RecvZP: -; LoadW $73, __drv1541_zp_RUN__ MoveW DDatas, $73 jmp Drv_RecvWord + .assert * < __DRIVE0300_START__ + $1ff, error, "Drv_Recv+DriveStart+DriveLoop+Drv_RecvZP must be within $0400-$04ff" + Drv_ExitTurbo: jsr D_DUNK4_1 LoadB $33, 0 @@ -1118,7 +1166,7 @@ Drv_ExitTurbo: pla PopB $49 plp - rts + jmp ($fffc) ; exit through reset vector Drv_ChngDskDev: lda DDatas @@ -1259,19 +1307,10 @@ Drv_NewDisk_8: sta $1c00 rts -D_DUNK8: ; LED off? - lda #$f7 - bne D_DUNK8_3 -D_DUNK8_1: ; LED on? - lda #$08 - ora $1c00 - bne Drv_NewDisk_8 - D_DUNK8_2: LoadB $20, 0 LoadB $3e, $ff lda #$fb -D_DUNK8_3: and $1c00 jmp Drv_NewDisk_8 From e85b4f55d307405488c564d8669d664d5f7c5b0d Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Sun, 31 Mar 2024 22:52:46 +0200 Subject: [PATCH 19/27] simplify ExitTurbo (reset only), used gained space to check for missing block header error --- drv/drv1541parallel.s | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 11b9bd56..22e37641 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1157,15 +1157,6 @@ Drv_RecvZP: .assert * < __DRIVE0300_START__ + $1ff, error, "Drv_Recv+DriveStart+DriveLoop+Drv_RecvZP must be within $0400-$04ff" Drv_ExitTurbo: - jsr D_DUNK4_1 - LoadB $33, 0 - sta $1800 - jsr $f98f ; turn drive motor off - LoadB $1c0c, $ec - pla - pla - PopB $49 - plp jmp ($fffc) ; exit through reset vector Drv_ChngDskDev: @@ -1489,6 +1480,7 @@ Drv_DoReadSector: LoadB $00, 1 ; no error by default + ldx #90 ; 90 attempts ; Wait for sync + compare encoded header (like DOS does) waitheader: jsr $f556 ; wait for sync @@ -1497,11 +1489,17 @@ waitheader: clv lda $1c01 cmp $24,y - bne waitheader ; next one + bne nextheader ; next one iny cpy #8 bne :- ; XXX ROM does check for maximum number of tries, error would jump to sendblock below with error $02 + beq foundheader +nextheader: dex + bne waitheader + LoadB $00, 2 ; 20, 'read error' + jmp Drv_ReadSec_DataOut +foundheader: ; code from Spindle 3.1 by lft, linusakesson.net/software/spindle/ ; Wait for a data block @@ -1557,6 +1555,7 @@ zp_return: sta $24 ; checksum +Drv_ReadSec_DataOut: ; send out data, compute checksum ldy #$ff sty $1803 ; port B output @@ -1574,8 +1573,9 @@ zp_return: cpy #0 bne :-- - ; compare checksum ($24==$25) - CmpB $24, $25 + CmpBI $00, 1 ; if there is error already + bne :+ ; return it + CmpB $24, $25 ; otherwise compare checksums beq :+ LoadB $00, 5 ; checksum error ; if header was found in time and checksum is OK then send status byte==1 From 0fb83439585cffb9f183e08044026abc35f85fa7 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Tue, 2 Apr 2024 23:16:45 +0200 Subject: [PATCH 20/27] corrected Enter/Exit/PurgeTurbo to correctly handle each case --- drv/drv1541parallel.s | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 22e37641..268b30bb 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -755,17 +755,20 @@ __EnterTurbo: jsr SetDevice ldx curDrive lda _turboFlags,x - bmi EntTur0 +;; bmi EntTur0 + bpl :+ + jmp EntTur3 +: jsr InitForIO jsr SendCODE beqx :+ - jmp EntTur5 -: ldx curDrive - lda #%10000000 - sta _turboFlags,x -EntTur0: - and #%01000000 - bne EntTur3 - jsr InitForIO + jmp EntTur4 +:; ldx curDrive +; lda #%10000000 +; sta _turboFlags,x +;;EntTur0: +; and #%01000000 +; bne EntTur3 +; jsr InitForIO ldx #>EnterCommand lda #DriveCode jsr Hst_SendByte jsr DoneWithIO ldx curDrive - lda _turboFlags,x - ora #%01000000 +;; lda _turboFlags,x +;; ora #%01000000 + lda #%11000000 sta _turboFlags,x EntTur3: ldx #0 @@ -829,6 +834,8 @@ SendExitTurbo: ldx #>Drv_ExitTurbo lda # Date: Wed, 3 Apr 2024 00:03:09 +0200 Subject: [PATCH 21/27] scan for 1541s on the bus and send M-W command to set port A as input --- kernal/start/start64.s | 223 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/kernal/start/start64.s b/kernal/start/start64.s index b8725583..700e9f28 100644 --- a/kernal/start/start64.s +++ b/kernal/start/start64.s @@ -68,6 +68,9 @@ ; _ResetHandle: +.ifdef drv1541parallel + jsr detect_1541s +.endif sei cld ldx #$FF @@ -130,6 +133,20 @@ ASSERT_NOT_BELOW_IO ; jsr FirstInit jsr MouseInit +.ifdef drv1541parallel + LoadB NUMDRV, 0 + ldy #8 +: lda drives,y + cmp #DRV_1541 + bne :+ + sta _driveType,y + inc NUMDRV +: iny + cpy #12 + bne :-- + LoadB curType, DRV_1541 + MoveB curDevice, curDrive +.else lda #currentInterleave sta interleave @@ -140,6 +157,7 @@ ASSERT_NOT_BELOW_IO lda #DRV_TYPE ; see config.inc sta curType sta _driveType,y +.endif ; This is the original code the cbmfiles version ; has at $5000. @@ -209,3 +227,208 @@ bootSec2: .byte 0 bootOffs: .byte 0 + +.ifdef drv1541parallel + +; ------------------------------------------ + +k_second = $ff93 +k_unlstn = $ffae +k_listen = $ffb1 +k_setlfs = $ffba +k_setnam = $ffbd +k_open = $ffc0 +k_close = $ffc3 +k_chkin = $ffc6 +k_clrchn = $ffcc +k_chrin = $ffcf +k_chrout = $ffd2 +k_getin = $ffe4 + +drives = *-8 + .byte 0, 0, 0, 0 + +; multiple daisy-chained parallel port connections work with 1541 (see DualDriveBurstBackup) +; but 1541 ROM will set port A to output upon boot ($FF10) - not clear why +; so we have to scan for all attached 1541s and run M-W,$1803,1,0 to set port A as input + +detect_1541s: + PushB CPU_DATA + PushB curDevice +ASSERT_NOT_BELOW_IO + LoadB CPU_DATA, KRNL_IO_IN + jsr drive_poll + ; copy discovered drive types + ldy #8 +: lda drives,y + cmp #DRV_1541 + bne :+ + jsr set1541PortAInput +: iny + cpy #12 + bne :-- + PopB curDevice + sta curDrive + PopB CPU_DATA + rts + +set1541PortAInput: + tya + pha + tax + lda #15 + tay + jsr k_setlfs + lda #7 + ldx #<@write1803 + ldy #>@write1803 + jsr k_setnam + jsr k_open + lda #15 + jsr k_close + pla + tay + rts + +@write1803: + .byte "M-W" + .word $1803 + .byte 1 + .byte 0 + +; drive detection code based on codebase64 solution https://codebase64.org/doku.php?id=base:detect_drives_on_iec_bus +; by Todd S. Elliott + +drive_poll: + + LoadB curDevice, 8 ; start at #8 + tay + lda #DRV_NULL ; that is actually 0 +: sta drives,y ; zero out the drive buffer + iny + cpy #12 + bne :- + + ; scan IEC bus, if devices exist +@iecloop: + ldy #0 + sty STATUS ; clear status + lda curDevice + jsr k_listen ; opens the device for listening + lda #$ff ; Secondary address - $0f OR'ed with $f0 to open + jsr k_second ; opens the channel with sa of 15 + + + bbsf 7, STATUS, @close ; branch if there is no device present + + ldy curDevice + tya + sta drives,y ; store non-zero in successful device number + +@close: jsr k_unlstn ; severs the serial bus control + + LoadB STATUS, 0 ; clear status + lda curDevice + jsr k_listen + lda #$ef ; sa - $0f and OR'ed with $e0 to close file + jsr k_second ; closes the channel with sa of 15 + jsr k_unlstn ; finally closes it + + inc curDevice ; next device + CmpBI curDevice, 12 ; last device to check? + bne @iecloop + + ldy #8 + sty curDevice ; restart at #8 + +@scanloop: + lda drives,y + bne @scandevice + iny + cpy #12 ; are we done? (acceptable range of 8 to 30) + bne @scanloop + rts ; exits the whole drive polling routine + +@scandevice: + sty curDevice + + jsr @open_cmd_channel + ldx #cbminfo + jsr @open_cmd_two + + jsr k_chrin ; gets the drive info + cmp #'5' ; is it '5' for the 15xx drives? + bne @not4171 + jsr k_chrin ; gets the next number + cmp #'4' ; is it '4' for the 1541? + bne @not41 + + lda #DRV_1541 ; indicates a 1541 at that device number + bne @get_next_drive + +@not41: cmp #'7' ; is it '7' for the 1571? + bne @not4171 + + lda #DRV_1571 ; indicates a 1571 at that device number + bne @get_next_drive + +@not4171: ; check for 1581 + jsr @close_cmd_channel + jsr @open_cmd_channel + ldx #info1581 + jsr @open_cmd_two + + jsr k_chrin ; gets the drive info + cmp #'5' ; is it a '5' for a 15xx drive? + bne @not81 + jsr k_chrin ; gets the next drive number + cmp #'8' ; is it a '8' for a 1581? + bne @not81 + + lda #DRV_1581 ; indicates a 1581 at that device number + bne @get_next_drive + +@not81: ; foreign drive exists, but mark it as a missing device (no built-in drivers) + lda #DRV_NULL + +@get_next_drive: + ldy curDevice + sta drives,y + jsr @close_cmd_channel + ldy curDevice + iny ; increment table offset + jmp @scanloop + +@close_cmd_channel: + jsr k_clrchn + lda #15 ; lfn + jmp k_close + +@open_cmd_channel: + lda #15 ; lfn + tay ; sa for command channel + ldx curDevice + jsr k_setlfs ; set up the open sequence + lda #6 ; length of command (m-r command) + rts + +@open_cmd_two: + jsr k_setnam ; sends the command + jsr k_open ; opens the file + ldx #15 ; lfn + jmp k_chkin ; redirect input + +cbminfo: ; gets CBM drive info at $e5c5 in drive ROM + .byte "M-R" + .word $e5c5 + .byte 2 + +info1581: ; gets 1581 drive info at $a6e8 in drive ROM + .byte "M-R" + .word $a6e8 + .byte 2 + +.endif + From 906bf88551132e0f25ecc522c9c8a5b2b3611a2b Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Wed, 3 Apr 2024 22:14:08 +0200 Subject: [PATCH 22/27] more corrections for uploading code to drive, handle ReadBlock without prior NewDisk (caused by Configure) --- drv/drv1541parallel.s | 70 +++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 268b30bb..5f5e9926 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -43,6 +43,10 @@ OPTIMAL_INTERLEAVE = 3 +DExeProc = $80 +DTrkSec = $82 +DTrkSecH = $83 + .segment "drv1541" _InitForIO: @@ -106,7 +110,7 @@ ReadBuff: jmp _ReadBuff WriteBuff: jmp _WriteBuff - jmp DUNK4_2 + jmp DUNK4_1 jmp GetDOSError AllocateBlock: jmp _AllocateBlock @@ -724,18 +728,19 @@ SndDOSCmd1: rts DUNK4: ; A/X addr of procedure to run, without parameters - stx z8c - sta z8b + stx DExeProc+1 + sta DExeProc ldy #2 ; 2 bytes to send bne DUNK4_3 DUNK4_1: ; A/X addr of procedure to run, r1 t&s parameters - stx z8c - sta z8b -DUNK4_2: ; called by NewDisk, but why send r1? - ldy #4 ; 4 bytes to send + pha MoveW r1, DTrkSec + pla +DUNK4_11: ; A/X addr of procedure to run, parameters in DTrkSec already + stx DExeProc+1 + sta DExeProc + ldy #4 ; 4 bytes to send DUNK4_3: - MoveW z8b, DExeProc LoadW z8b, DExeProc jmp Hst_SendByte @@ -789,25 +794,25 @@ __EnterTurbo: ; fast send rest of drive code: pages $03-$07 LoadB EntTH+1, >DriveCode - LoadW r1, __DRIVE0300_START__ ; target address + LoadW DTrkSec, __DRIVE0300_START__ ; target address EntTur1: ldx #>Drv_RecvZP ; recieve data lda #DriveCode sta z8c ldy #0 jsr Hst_SendByte - inc r1H + inc DTrkSecH inc EntTH+1 - CmpBI r1H, $08 + CmpBI DTrkSecH, $08 bne EntTur1 ; send page 7 data also to page 2 - LoadB r1H, $02 + LoadB DTrkSecH, $02 ldx #>Drv_RecvZP lda #Drv_NewDisk + lda #Drv_RecvZP ; recieve data lda # Date: Wed, 3 Apr 2024 22:32:02 +0200 Subject: [PATCH 23/27] remove all code related to disk cache, no space for that --- drv/drv1541parallel.s | 136 +----------------------------------------- 1 file changed, 2 insertions(+), 134 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 5f5e9926..f0611b4c 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -156,9 +156,6 @@ SetDirHead: rts CheckParams: - bbrf 6, curType, CheckParams_1 - jsr DoCacheVerify - beq CheckParams_2 CheckParams_1: lda #0 sta errCount @@ -183,12 +180,7 @@ __OpenDisk: bnex OpenDsk1 jsr GetDirHead bnex OpenDsk1 - bbrf 6, tmpDriveType, OpenDsk0 - jsr DoCacheVerify - beq OpenDsk0 - jsr DoClearCache jsr SetDirHead - jsr DoCacheWrite OpenDsk0: LoadW r5, curDirHead jsr ChkDkGEOS @@ -760,21 +752,13 @@ __EnterTurbo: jsr SetDevice ldx curDrive lda _turboFlags,x -;; bmi EntTur0 bpl :+ jmp EntTur3 : jsr InitForIO jsr SendCODE beqx :+ jmp EntTur4 -:; ldx curDrive -; lda #%10000000 -; sta _turboFlags,x -;;EntTur0: -; and #%01000000 -; bne EntTur3 -; jsr InitForIO - ldx #>EnterCommand +: ldx #>EnterCommand lda #Drv_ReadSec ; read sector and status @@ -1002,16 +980,13 @@ RdBlock0: ldy #0 jsr Hst_RecvByte jsr GetDError - beqx RdBlock1 + beq RdBlock1 inc errCount cpy errCount beq RdBlock1 bcs RdBlock0 RdBlock1: bnex RdBlock2 - bbrf 6, curType, RdBlock2 - jsr DoCacheWrite - bra RdBlock2 RdBlock2: ldy #0 rts @@ -1707,113 +1682,6 @@ zpc_bne: .byt $d0,BNE_WITHOUT_NOP ; 59 60 61 bne zpc_loop .segment "drv1541_b" -; there is no space for cache code and tables anymore with disk driver area, so no Shadow 1541 possible - .ifndef notpossible -ClearCache: -DoClearCache: -DoCacheRead: -DoCacheWrite: -DoCacheVerify: - rts -.else -ClrCacheDat: - .word 0 - -ClearCache: - bbsf 6, curType, DoClearCache - rts -DoClearCache: - LoadW r0, ClrCacheDat - ldy #0 - sty r1L - sty r1H - sty r2H - iny - iny - sty r2L - iny - sty r3H - ldy curDrive - lda driveData,y - sta r3L -DoClrCache1: - jsr StashRAM - inc r1H - bne DoClrCache1 - inc r3L - dec r3H - bne DoClrCache1 - rts - -DoCacheRead: - ldy #%10010001 - jsr DoCacheDisk - ldy #0 - lda (r4),y - iny - ora (r4),y - rts - -GiveNoError: - ldx #0 - rts - -DoCacheVerify: - ldy #%10010011 - jsr DoCacheDisk - and #$20 - rts - -DoCacheWrite: - ldy #%10010000 -DoCacheDisk: - PushW r0 - PushW r1 - PushW r2 - PushB r3L - tya - pha - ldy r1L - dey - lda CacheTabL,y - add r1H - sta r1H - lda CacheTabH,y - ldy curDrive - adc driveData,y - sta r3L - ldy #0 - sty r1L - sty r2L - iny - sty r2H - MoveW r4, r0 - pla - tay - jsr DoRAMOp - tax - PopB r3L - PopW r2 - PopW r1 - PopW r0 - txa - ldx #0 - rts - -CacheTabL: - .byte $00, $15, $2a, $3f, $54, $69, $7e, $93 - .byte $a8, $bd, $d2, $e7, $fc, $11, $26, $3b - .byte $50, $65, $78, $8b, $9e, $b1, $c4, $d7 - .byte $ea, $fc, $0e, $20, $32, $44, $56, $67 - .byte $78, $89, $9a, $ab -CacheTabH: - .byte $00, $00, $00, $00, $00, $00, $00, $00 - .byte $00, $00, $00, $00, $00, $01, $01, $01 - .byte $01, $01, $01, $01, $01, $01, $01, $01 - .byte $01, $01, $02, $02, $02, $02, $02, $02 - .byte $02, $02, $02, $02 -.endif - tmpclkreg: .byte 0 tmpPS: From 8782f756dd3199c25979f2db9fc939afed8d8119 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Wed, 3 Apr 2024 23:03:17 +0200 Subject: [PATCH 24/27] correct ExitTurbo to preserve device number --- drv/drv1541parallel.s | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index f0611b4c..329bc0d1 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1142,13 +1142,22 @@ Drv_RecvZP: .assert * < __DRIVE0300_START__ + $1ff, error, "Drv_Recv+DriveStart+DriveLoop+Drv_RecvZP must be within $0400-$04ff" Drv_ExitTurbo: + jsr Drv_LedOFF + ldy $78 ; preserve device number lax #0 : sta $00,x sta $0200,x inx bne :- bit $1801 ; final sync - jmp $eb22 ; reset routine, after RAM/ROM test + LoadB $180c, $01 ; CA1 (ATN IN) trigger on positive edge + lda #$82 + sta $180d ; interrupt possible through ATN IN + sta $180e + ldx #$45 + txs + tya ; restore device number ($78) + jmp $eb45 ; reset routine, after RAM/ROM test when device number is set Drv_ChngDskDev: lda DDatas From a4113b9147e3e42fea1ad84401f019e397c9bd58 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Wed, 3 Apr 2024 23:24:37 +0200 Subject: [PATCH 25/27] don't send page 07xx twice, move ExitTurbo to the end to fit whole WriteSector under 0x700 --- drv/drv1541parallel.s | 52 ++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index 329bc0d1..b013a3f5 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -789,9 +789,10 @@ EntTH: lda #>DriveCode jsr Hst_SendByte inc DTrkSecH inc EntTH+1 - CmpBI DTrkSecH, $08 + CmpBI DTrkSecH, $07 bne EntTur1 ; send page 7 data also to page 2 + inc z8c LoadB DTrkSecH, $02 ldx #>Drv_RecvZP lda # Date: Thu, 4 Apr 2024 21:20:28 +0200 Subject: [PATCH 26/27] reorder drivecode to send fewer bytes via slow M-W --- drv/drv1541parallel.s | 62 ++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index b013a3f5..c8b9f9b4 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -789,10 +789,9 @@ EntTH: lda #>DriveCode jsr Hst_SendByte inc DTrkSecH inc EntTH+1 - CmpBI DTrkSecH, $07 + CmpBI DTrkSecH, >(__DRIVE0300_LAST__) bne EntTur1 - ; send page 7 data also to page 2 - inc z8c + ; send page 7 data to page 2 LoadB DTrkSecH, $02 ldx #>Drv_RecvZP lda #DriveCode jsr Hst_SendByte jsr DoneWithIO ldx curDrive -;; lda _turboFlags,x -;; ora #%01000000 lda #%11000000 sta _turboFlags,x EntTur3: @@ -835,7 +832,7 @@ SendExitTurbo: SendCODE: LoadW z8d, DriveCode+$0100 ; skip over first page (gcr decode, send only 1 page of code) LoadW WriteAddy, __DRIVE0300_START__+$0100 - LoadB z8f, <($00ff/$20) + LoadB z8f, <( (Drv_END_MW_CODE-__DRIVE0300_START__-$0100) / $0020) SndCDE0: jsr SendCHUNK bnex SndCDE1 @@ -1049,24 +1046,6 @@ DLastOper = $0e ; 1 if $0700-$0790 has to be restored after write gcrdecode: .byte $03, $99, $99, $99, $99, $99, $99, $99, $99, $80, $00, $10, $99, $c0, $40, $50, $99, $99, $20, $30, $99, $f0, $60, $70, $99, $90, $a0, $b0, $99, $d0, $e0, $7f, $76, $80, $99, $90, $99, $99, $99, $76, $7f, $08, $00, $01, $99, $0c, $04, $05, $99, $99, $02, $03, $99, $0f, $06, $07, $99, $09, $0a, $0b, $99, $0d, $0e, $99, $99, $00, $20, $a0, $6c, $4c, $2c, $0c, $80, $08, $08, $0c, $99, $0f, $09, $0d, $00, $00, $08, $99, $00, $99, $01, $99, $10, $01, $0c, $99, $04, $99, $05, $99, $99, $10, $30, $b0, $02, $99, $03, $99, $c0, $0c, $0f, $99, $06, $99, $07, $99, $40, $04, $09, $99, $0a, $99, $0b, $99, $50, $05, $0d, $99, $0e, $90, $00, $d0, $40, $99, $20, $e0, $60, $80, $a0, $c0, $e0, $99, $00, $04, $02, $06, $0a, $0e, $20, $02, $18, $99, $10, $99, $11, $99, $30, $03, $1c, $99, $14, $99, $15, $99, $99, $c0, $f0, $d0, $12, $99, $13, $99, $f0, $0f, $1f, $99, $16, $99, $17, $99, $60, $06, $19, $99, $1a, $99, $1b, $99, $70, $07, $1d, $99, $1e, $a4, $a4, $a4, $a3, $40, $60, $e0, $15, $13, $12, $11, $90, $09, $01, $05, $03, $07, $0b, $99, $a0, $0a, $99, $99, $99, $99, $99, $99, $b0, $0b, $99, $99, $99, $99, $99, $99, $99, $50, $70, $99, $99, $99, $99, $99, $d0, $0d, $99, $99, $99, $99, $99, $99, $e0, $0e, $99, $99, $99, $99, $99, $99, $99, $99, $99, $99, $99, $99, $99, $99 - -Drv_SendByte_0: - LoadB $1803, $ff ; send length (1) and status byte from $00 -Drv_SendStatus: - LoadB $1801, $01 ; send length - lda #$10 -: bit $180d ; wait for handshake - beq :- - bit $1800 ; clear flag - ldy $00 - sty $1801 ; send status -: bit $180d ; wait for handshake - beq :- - bit $1800 ; clear flag - LoadB $1803, $00 ; port A input - rts - - Drv_RecvWord: ldy #1 jsr Drv_RecvByte @@ -1088,14 +1067,6 @@ Drv_RecvByte_1: bne Drv_RecvByte_1 rts -D_DUNK4: - dec $48 - bne D_DUNK4_1 - jsr D_DUNK8_2 -D_DUNK4_1: - LoadB $1800, 0 - rts - DriveStart: php sei @@ -1140,7 +1111,24 @@ Drv_RecvZP: MoveW DDatas, $73 jmp Drv_RecvWord - .assert * < __DRIVE0300_START__ + $1ff, error, "Drv_Recv+DriveStart+DriveLoop+Drv_RecvZP must be within $0400-$04ff" +Drv_END_MW_CODE: ; marker for end of code that has to be sent via M-W command + +Drv_SendByte_0: + LoadB $1803, $ff ; send length (1) and status byte from $00 +Drv_SendStatus: + LoadB $1801, $01 ; send length + lda #$10 +: bit $180d ; wait for handshake + beq :- + bit $1800 ; clear flag + ldy $00 + sty $1801 ; send status +: bit $180d ; wait for handshake + beq :- + bit $1800 ; clear flag + LoadB $1803, $00 ; port A input + rts + Drv_ExitTurbo: jsr Drv_RestorePage7 @@ -1153,6 +1141,14 @@ Drv_ChngDskDev: sta $78 rts +D_DUNK4: + dec $48 + bne D_DUNK4_1 + jsr D_DUNK8_2 +D_DUNK4_1: + LoadB $1800, 0 + rts + D_DUNK5: jsr D_DUNK12 lda $22 From 9bc60289fc345dbab09ada506c7abc6cf2e24039 Mon Sep 17 00:00:00 2001 From: Maciej Witkowiak Date: Thu, 4 Apr 2024 21:49:34 +0200 Subject: [PATCH 27/27] docs --- drv/drv1541parallel.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drv/drv1541parallel.s b/drv/drv1541parallel.s index c8b9f9b4..66adeb2c 100755 --- a/drv/drv1541parallel.s +++ b/drv/drv1541parallel.s @@ -1,9 +1,9 @@ ; GEOS by Berkeley Softworks ; reverse engineered by Maciej Witkowiak, Michael Steil ; +; On the fly sector read and GCR decoding code from Spindle 3.1 by lft, linusakesson.net/software/spindle/ +; ; Commodore 1541 disk driver with parallel cable by Maciej Witkowiak -; NOTE: OPTIMAL_INTERLEAVE has to be determined experimentally -; NOTE2: if drive code jams - check if 'jmp (DExecAddy)' is on page boundary - it's dangerously close .include "const.inc" .include "geossym.inc"