one more init rework, turbo tape starts working

This commit is contained in:
FeralChild64 committed 2019-11-01 09:54:32 +01:00
1 parent c32fbadc7c
commit e145bb6c86
14 files changed
+167 -130

No files matched your search

+8 -2
View File
@@ -103,6 +103,12 @@ Adds support for the IEEC bus - for serial printers, disk drives, etc.
Needs over 1000 bytes in KERNAL segment. If unsure - enable. Needs over 1000 bytes in KERNAL segment. If unsure - enable.
### `CONFIG_TAPE_TURBO`
Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action Replay_ and _Final_ cartridges)
Needs about 350 bytes in KERNAL segment. If unsure - enable.
## Multiple SID support ## Multiple SID support
The SID is a sound chip - original machine had one installed. However, mods exists to add more of them for improved sound capabilitiee. Emulators and FPGA machines typically allow to simulate more than one too. Unfortunately, there is no standard regarding how these additional chips are visible in the processor address space, and there is no sane way to detect it - thus, it has to be configurable. The SID is a sound chip - original machine had one installed. However, mods exists to add more of them for improved sound capabilitiee. Emulators and FPGA machines typically allow to simulate more than one too. Unfortunately, there is no standard regarding how these additional chips are visible in the processor address space, and there is no sane way to detect it - thus, it has to be configurable.
@@ -113,7 +119,7 @@ The SID support in the ROM is very limited - it only disables the sound during s
Each of them add support for one additional SID - addresses should be given in `CONFIG_SID_2ND_ADDRESS` and `CONFIG_SID_3RD_ADDRESS`, respectively. Each of them add support for one additional SID - addresses should be given in `CONFIG_SID_2ND_ADDRESS` and `CONFIG_SID_3RD_ADDRESS`, respectively.
Each of these options needs 8 bytes in KERNAL segment. Each of these options needs 3 bytes in KERNAL segment.
### `CONFIG_SID_D4XX` and `CONFIG_SID_D5XX` ### `CONFIG_SID_D4XX` and `CONFIG_SID_D5XX`
@@ -181,7 +187,7 @@ Needs 25 bytes more space in KERNAL segment for the code. In addition, each conf
### `CONFIG_EDIT_STOPQUOTE` ### `CONFIG_EDIT_STOPQUOTE`
If enabled, STOP key terminates insert/quote mode (like on BlackBox cartridge). If enabled, STOP key terminates insert/quote mode (like on some _Black Box_ cartridges).
Feature needs 12 bytes in KERNAL segment. If unsure - enable. Feature needs 12 bytes in KERNAL segment. If unsure - enable.
+8 -3
View File
@@ -20,6 +20,10 @@ NOTE: extra features and their syntax can change in the future!
# Features missing # Features missing
The following ROM features are currently missing and are not planned due to space considerations:
* full tape support - VERIFY, SAVE, sequential files; tape is considered a legacy medium, so it's support is going to be limited
* mock 6551 emulation - this inly slows down the RS-232 support for original ROMs, probably noone needs it
The following ROM features are currently missing: The following ROM features are currently missing:
@@ -27,7 +31,8 @@ The following ROM features are currently missing:
* BASIC variables * BASIC variables
* BASIC expression parsing * BASIC expression parsing
* floating point routines * floating point routines
* tape support * tape (normal mode) support
* IEC support for SAVE
* RS-232 support * RS-232 support
* NMI handling is incomplete * NMI handling is incomplete
@@ -104,8 +109,8 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on
| :-------: | :--------: | :---------- | :------: | :--------------------------------------------------: | | :-------: | :--------: | :---------- | :------: | :--------------------------------------------------: |
| `($028F)` | | `KEYLOG` | DONE | | | `($028F)` | | `KEYLOG` | DONE | |
| `$FF81` | `$FF5B` | `CINT` | DONE | | | `$FF81` | `$FF5B` | `CINT` | DONE | |
| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization might be incomplete | | `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete |
| `$FF87` | `$FD50` | `RAMTAS` | PARTIAL | probably shouldn't touch VIC and CIA's | | `$FF87` | `$FD50` | `RAMTAS` | DONE | |
| `$FF8A` | `$FD15` | `RESTOR` | DONE | | | `$FF8A` | `$FD15` | `RESTOR` | DONE | |
| `$FF8D` | `$FD1A` | `VECTOR` | DONE | | | `$FF8D` | `$FD1A` | `VECTOR` | DONE | |
| `$FF90` | | `SETMSG` | DONE | | | `$FF90` | | `SETMSG` | DONE | |
+1 -1
View File
@@ -43,7 +43,7 @@
#define CONFIG_IEC #define CONFIG_IEC
// #define CONFIG_IEC_JIFFYDOS // please keep disabled for now // #define CONFIG_IEC_JIFFYDOS // please keep disabled for now
// #define CONFIG_TAPE_NORMAL // please keep disabled for now // #define CONFIG_TAPE_NORMAL // please keep disabled for now
// #define CONFIG_TAPE_TURBO // please keep disabled for now #define CONFIG_TAPE_TURBO
// #define CONFIG_RS232_UP2400 // please keep disabled for now // #define CONFIG_RS232_UP2400 // please keep disabled for now
// #define CONFIG_RS232_UP9600 // please keep disabled for now // #define CONFIG_RS232_UP9600 // please keep disabled for now
+1 -1
View File
@@ -45,7 +45,7 @@
#define CONFIG_IEC #define CONFIG_IEC
// #define CONFIG_IEC_JIFFYDOS // please keep disabled for now // #define CONFIG_IEC_JIFFYDOS // please keep disabled for now
// #define CONFIG_TAPE_NORMAL // please keep disabled for now // #define CONFIG_TAPE_NORMAL // please keep disabled for now
// #define CONFIG_TAPE_TURBO // please keep disabled for now #define CONFIG_TAPE_TURBO
// #define CONFIG_RS232_UP2400 // please keep disabled for now // #define CONFIG_RS232_UP2400 // please keep disabled for now
// #define CONFIG_RS232_UP9600 // please keep disabled for now // #define CONFIG_RS232_UP9600 // please keep disabled for now
+1 -1
View File
@@ -44,7 +44,7 @@
#define CONFIG_IEC #define CONFIG_IEC
// #define CONFIG_IEC_JIFFYDOS // please keep disabled for now // #define CONFIG_IEC_JIFFYDOS // please keep disabled for now
// #define CONFIG_TAPE_NORMAL // please keep disabled for now // #define CONFIG_TAPE_NORMAL // please keep disabled for now
// #define CONFIG_TAPE_TURBO // please keep disabled for now #define CONFIG_TAPE_TURBO
// #define CONFIG_RS232_UP2400 // please keep disabled for now // #define CONFIG_RS232_UP2400 // please keep disabled for now
// #define CONFIG_RS232_UP9600 // please keep disabled for now // #define CONFIG_RS232_UP9600 // please keep disabled for now
+1 -1
View File
@@ -43,7 +43,7 @@
#define CONFIG_IEC #define CONFIG_IEC
// #define CONFIG_IEC_JIFFYDOS // please keep disabled for now // #define CONFIG_IEC_JIFFYDOS // please keep disabled for now
// #define CONFIG_TAPE_NORMAL // please keep disabled for now // #define CONFIG_TAPE_NORMAL // please keep disabled for now
// #define CONFIG_TAPE_TURBO // please keep disabled for now #define CONFIG_TAPE_TURBO
// #define CONFIG_RS232_UP2400 // please keep disabled for now // #define CONFIG_RS232_UP2400 // please keep disabled for now
// #define CONFIG_RS232_UP9600 // please keep disabled for now // #define CONFIG_RS232_UP9600 // please keep disabled for now
-2
View File
@@ -299,8 +299,6 @@
.eval features_str = ADD_FEATURE(features_str, "TAPE NORMAL+TURBO") .eval features_str = ADD_FEATURE(features_str, "TAPE NORMAL+TURBO")
#endif #endif
.eval feature_new_line = true
#if CONFIG_IEC #if CONFIG_IEC
.eval features_str = ADD_FEATURE(features_str, "IEC") .eval features_str = ADD_FEATURE(features_str, "IEC")
#endif #endif
+5 -4
View File
@@ -10,12 +10,9 @@ hw_entry_reset:
sei // disable the interrupts, as fast as possible - they are disabled in case of HW reset, sei // disable the interrupts, as fast as possible - they are disabled in case of HW reset,
// but this routine can be also called manually // but this routine can be also called manually
ldx #$00
sta VIC_SCROLX // turn the display off - we want as little screen artifacts as possible
cld // required for all CPUs - due to possibility of manual call cld // required for all CPUs - due to possibility of manual call
dex // $FF - to initialize stack pointer ldx #$FF
txs txs
// The following routine is based on reading the public KERNAL jumptable routine // The following routine is based on reading the public KERNAL jumptable routine
@@ -28,6 +25,10 @@ hw_entry_reset:
bne !+ bne !+
jmp (ICART_COLD_START) jmp (ICART_COLD_START)
!: !:
// Disable the screen (and set 40 columns) to prevent visual glitches later
ldx #$28
stx VIC_SCROLX
// Initialising IO is obviously required. Also indicated by c64 prg p269. // Initialising IO is obviously required. Also indicated by c64 prg p269.
jsr JIOINIT jsr JIOINIT
-6
View File
@@ -1,6 +0,0 @@
// Our implementation is longer than the original one,
// placing it here would cause a collision with OPEN
RAMTAS:
jmp ramtas_real
@@ -8,52 +8,33 @@
// CPU registers that has to be preserved (see [RG64]): none // CPU registers that has to be preserved (see [RG64]): none
// //
ramtas_real: RAMTAS:
// C64 Programmer's Reference guide p291: // C64 Programmer's Reference guide p291:
// Clear $0000-$0101, $0200-$03ff // Clear $0000-$0101, $0200-$03ff
// PGS: $0000, $0001 are CPU IO ports, so shouldn't get written to // PGS: $0000, $0001 are CPU IO ports, so shouldn't get written to
ldy #$02
lda #$00
!:
sta $00,y
iny
bne !-
!:
// How many ways are there to efficiently erase these two pages // How many ways are there to efficiently erase these two pages
// of RAM? We would like to avoid any unnecessary byte similarity // of RAM? We would like to avoid any unnecessary byte similarity
// with the C64 KERNAL. Thus we do $0300 before $0200, even though // with the C64 KERNAL. Thus we do $0300 before $0200, even though
// with the longer sequence of identicale bytes we see no basis for // with the longer sequence of identicale bytes we see no basis for
// it being copyrightable. Again, we just want to redue the attack // it being copyrightable. Again, we just want to redue the attack
// surface for any misguided suit. // surface for any misguided suit.
ldy #$00
lda #$00
!:
sta $0300,Y sta $0300,Y
sta $0200,Y sta $0200,Y
sta $0002,Y // that's why we don't use .X for index, we do not want zeropage addressing here!
iny iny
bne !- bne !-
// Allocate cassette buffer // Allocate cassette buffer
// "Mapping the C64", p237 ldx #<$033C
lda #<$033C stx TAPE1+0
sta TAPE1+0 ldx #>$033C
lda #>$033C stx TAPE1+1
sta TAPE1+1
// set screen address to $0400
// https://www.c64-wiki.com/wiki/Screen_RAM
// Since we are setting $D018, we also make sure we are using the
// ROM character set (C64 Programmer's Reference Guide p322)
lda #$14
sta VIC_YMCSB
// Make sure we have the correct VIC-II memory bank for the screen to really be at $0400
// and not $4400, $8400 or $C400
// https://www.c64-wiki.com/wiki/VIC_bank#Selecting_VIC_banks
lda CIA2_DDRA
ora #$03
sta CIA2_DDRA
lda CIA2_PRA
ora #$03
sta CIA2_PRA
// Set screen address pointer ("Compute's Mapping the 64" p238) // Set screen address pointer ("Compute's Mapping the 64" p238)
// This is obvious boiler plate containing no creative input, but to avoid // This is obvious boiler plate containing no creative input, but to avoid
@@ -62,30 +43,41 @@ ramtas_real:
ldx #>$0400 ldx #>$0400
stx HIBASE stx HIBASE
// Work out RAM size and put in MEMSTR and MEMSIZK // Set BASIC start text pointer
// "Compute's Mapping the 64", p54 // (remember, that low memory is 0 initialized at this moment)
// http://unusedino.de/ec64/technical/project64/mapping_c64.html
ldx #>$0800 ldx #>$0800
stx MEMSTR+1 stx MEMSTR+1
ldx #$00
stx MEMSTR+0 // Work out RAM size and put in MEMSIZK
stx MEMSIZK+0
// Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF // Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF
ldx $8000 ldx $8000
inx inx
stx $8000 stx $8000
cpx $8000 cpx $8000
bne ramtas_32K_RAM bne ramtas_32k
// FALLTROUGH
ramtas_40k:
// 40K RAM - restore memory content, set MEMSIZK
ldy #$A0
!:
sty MEMSIZK+1
// Always restore memory, cartridge might have RAM under ROM
dex dex
stx $8000 stx $8000
ldx #$A0
stx MEMSIZK+1
bne !+ // always non-zero, saves one byte
ramtas_32K_RAM:
dex
stx $8000 // case there is RAM under the ROM
ldx #$80
stx MEMSIZK+1
!:
rts rts
ramtas_32k:
// 32K RAM - restore memory content, set MEMSIZK
ldy #$80
bne !- // branch always
+83 -56
View File
@@ -11,39 +11,71 @@
IOINIT: IOINIT:
// Set $00/$01 port mode and value //
// First initialize the CPU port, to make sure we have correct memory map
//
// We want BASIC and KERNAL ROMs mapped, and datasette motor off // We want BASIC and KERNAL ROMs mapped, and datasette motor off
// (https://www.c64-wiki.com/wiki/Zeropage) // (https://www.c64-wiki.com/wiki/Zeropage)
// Work around for VICE bug: Writing $00 before $01 results in rubbish in $01 // Work around for VICE bug: Writing $00 before $01 results in rubbish in $01
// after. https://sourceforge.net/p/vice-emu/bugs/1057/ // after. https://sourceforge.net/p/vice-emu/bugs/1057/
lda #$27 ldx #$27
stx CPU_R6510
ldx #$EF ldx #$EF
sta CPU_R6510
stx CPU_D6510 // [CM64] page 4 stx CPU_D6510 // [CM64] page 4
// Silence the SID chips, depending on the configuration //
// Now prevent the CIAs from generating interrupts, who knows what damage they can do
//
// Disable IRQ generation for both CIAs - see [CM64], page 149
ldx #$7F
stx CIA1_ICR // $DC0D
stx CIA2_ICR // $DD0D
// See discussion here:
// https://www.lemon64.com/forum/viewtopic.php?t=41744&sid=e294c254db2ba671cde643f100aae341
// It seems that initializing this register to $7F is the best idea - UDTIM key scanning
// also leaves this at $7F
stx CIA1_PRA // $DC00
//
// Now silence the SID chip(s), depending on the configuration - we want them silent ASAP
//
// First the standard chip (skip if it is covered by whole $D4XX range)
lda #$00
#if !CONFIG_SID_D4XX #if !CONFIG_SID_D4XX
lda SID_SIGVOL
and #$F0
sta SID_SIGVOL sta SID_SIGVOL
#endif // !CONFIG_SID_D4XX #endif // !CONFIG_SID_D4XX
// Silence manually configured 2nd and 3rd SIDs
#if CONFIG_SID_2ND
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
#endif // CONFIG_SID_2ND
#if CONFIG_SID_3RD
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_3RD_ADDRESS
#endif // CONFIG_SID_3RD
// Silence whole D4XX and D5XX ranges (if configured)
#if CONFIG_SID_D4XX || CONFIG_SID_D5XX #if CONFIG_SID_D4XX || CONFIG_SID_D5XX
ldy #$00 ldy #$00
!: !:
#if CONFIG_SID_D4XX #if CONFIG_SID_D4XX
lda SID_SIGVOL, Y sta SID_SIGVOL + $000, Y
and #$F0
sta SID_SIGVOL, Y
#endif // CONFIG_SID_D4XX #endif // CONFIG_SID_D4XX
#if CONFIG_SID_D5XX #if CONFIG_SID_D5XX
// SIDs under $D5xx
lda SID_SIGVOL + $100, Y
and #$F0
sta SID_SIGVOL + $100, Y sta SID_SIGVOL + $100, Y
#endif // CONFIG_SID_D4XX #endif // CONFIG_SID_D4XX
@@ -52,50 +84,20 @@ IOINIT:
adc #$20 adc #$20
tay tay
bne !- bne !-
#endif // CONFIG_SID_D4XX || CONFIG_SID_D5XX #endif // CONFIG_SID_D4XX || CONFIG_SID_D5XX
#if CONFIG_SID_2ND //
lda SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS // Now continue the CIAs initialization
and #$F0 //
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
#endif // CONFIG_SID_2ND
#if CONFIG_SID_3RD // For CIA #1 we need port A as output and port B as input to scan the keyboard
lda SID_SIGVOL - __SID_BASE + CONFIG_SID_3RD_ADDRESS
and #$F0
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_3RD_ADDRESS
#endif // CONFIG_SID_3RD
// Initialize CIAs
// XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
// Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037)
// First disable IRQ generation for both CIA's
lda #$7F
sta CIA2_ICR
sta CIA1_ICR
// Enable timer interrupt
lda #$81
sta CIA1_ICR
// Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
lda #$11
sta CIA1_CRA
lda CIA1_ICR
// Setup the CIA1 for reading the keyboard - 'POKE 56322, 0' on original ROMs proves this
// is done during initialization, not during the interrupt
ldx #$FF ldx #$FF
stx CIA1_DDRA // output stx CIA1_DDRA // $DC02
inx // $00 inx
stx CIA1_DDRB // input stx CIA1_DDRB // $DC03
stx CIA2_DDRB // $DD03 // XXX this port is used for RS-232, value here is most likely wrong!
// Value checked on original ROM
stx CIA2_DDRA
#if CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK #if CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK
@@ -104,13 +106,38 @@ IOINIT:
#endif #endif
// Set DDR on CIA2 for IEC bus, VIC-II banking // Set DDR on CIA2 for IEC bus, VIC-II banking (see [CM64], $DDOO description on page 193)
lda #$3F lda #$3F
sta CIA2_DDRA sta CIA2_DDRA // $DD02
// Set VIC-II bank - needed at least for 'Operacja Proboszcz' game // XXX detect TOD clock, see https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
lda #%00000011
sta CIA2_PRA // XXX how to initialize these timers???
// stx CIA1_CRB // $DC0F
// stx CIA2_CRA // $DD0E
// stx CIA2_CRB // $DD0F
// Set VIC-II bank - at least the 'Operacja Proboszcz' game needs this within IOINIT
// Checked on original ROMs, that it sets bit #2 (RS-232 output) high
ldx #%00000111 // XXX adapt this to IEC idle state, JMP at the end won't be needed
stx CIA2_PRA // $DD00
//
ldy #<16421
ldx #>16421
sty CIA1_TIMALO // $DC04
stx CIA1_TIMAHI // $DC05
// Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
ldx #$11
stx CIA1_CRA // $DC0E
// Enable timer interrupt
ldx #$81
stx CIA1_ICR // $DC0D
#if CONFIG_IEC #if CONFIG_IEC
+4 -4
View File
@@ -32,7 +32,7 @@ setup_pal:
// ldx #>16380 // ldx #>16380
// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), // PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
// is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles // is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) CPU cycles
ldy #<16421 ldy #<16421
ldx #>16421 ldx #>16421
@@ -43,8 +43,8 @@ setup_pal:
setup_pal_ntsc_end: setup_pal_ntsc_end:
sty CIA1_TIMALO sty CIA1_TIMALO // $DC04
stx CIA1_TIMAHI stx CIA1_TIMAHI // $DC05
sta TVSFLG sta TVSFLG
@@ -55,7 +55,7 @@ setup_ntsc:
// Set timer interval to ~1/60th of a second // Set timer interval to ~1/60th of a second
// NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), // NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
// is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles // is clocked at 1.022727 MHz, so that 1/60s is 17045 ($4295) CPU cycles
ldy #<17045 ldy #<17045
ldx #>17045 ldx #>17045
+13 -3
View File
@@ -12,6 +12,8 @@
load_tape_turbo: load_tape_turbo:
// XXX prepare SID, store screen color somewhere, read header
jsr tape_ditch_verify // only LOAD is supported, no VERIFY jsr tape_ditch_verify // only LOAD is supported, no VERIFY
ldy #$00 ldy #$00
@@ -91,16 +93,24 @@ tape_turbo_get_bit:
lda #$10 lda #$10
!: !:
bit CIA2_ICR bit CIA1_ICR
beq !- // busy loop to detect signal beq !- // busy loop to detect signal
lda CIA2_ICR lda CIA2_ICR
pha pha
lda #$19 lda #$19
sta CIA2_CRA sta CIA2_CRA
pla pla
sta VIC_EXTCOL // use bitvalue as d020 effect (I love that one)
lsr
pha // audio/video effects
asl
sta SID_SIGVOL
beq !+
lda #$06
!:
sta VIC_EXTCOL
pla
lsr
rts rts
+4
View File
@@ -45,6 +45,8 @@ tape_ask_play:
ldx #__MSG_KERNAL_PRESS_PLAY ldx #__MSG_KERNAL_PRESS_PLAY
jsr print_kernal_message jsr print_kernal_message
// FALLTROUGH
tape_wait_button_loop: tape_wait_button_loop:
jsr udtim_keyboard jsr udtim_keyboard
@@ -72,6 +74,7 @@ tape_load_success:
jsr screen_show jsr screen_show
jsr tape_motor_off jsr tape_motor_off
cli
jmp lvs_success_end jmp lvs_success_end
@@ -80,6 +83,7 @@ tape_load_error:
jsr screen_show jsr screen_show
jsr tape_motor_off jsr tape_motor_off
cli
jmp lvs_load_verify_error jmp lvs_load_verify_error