one more init rework, turbo tape starts working
This commit is contained in:
1 parent
c32fbadc7c
commit
e145bb6c86
14 files changed
+168
-131
No files matched your search
@@ -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.
|
||||
|
||||
### `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
|
||||
|
||||
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 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`
|
||||
|
||||
@@ -181,7 +187,7 @@ Needs 25 bytes more space in KERNAL segment for the code. In addition, each conf
|
||||
|
||||
### `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.
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ NOTE: extra features and their syntax can change in the future!
|
||||
|
||||
# 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:
|
||||
|
||||
@@ -27,7 +31,8 @@ The following ROM features are currently missing:
|
||||
* BASIC variables
|
||||
* BASIC expression parsing
|
||||
* floating point routines
|
||||
* tape support
|
||||
* tape (normal mode) support
|
||||
* IEC support for SAVE
|
||||
* RS-232 support
|
||||
* 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 | |
|
||||
| `$FF81` | `$FF5B` | `CINT` | DONE | |
|
||||
| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization might be incomplete |
|
||||
| `$FF87` | `$FD50` | `RAMTAS` | PARTIAL | probably shouldn't touch VIC and CIA's |
|
||||
| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete |
|
||||
| `$FF87` | `$FD50` | `RAMTAS` | DONE | |
|
||||
| `$FF8A` | `$FD15` | `RESTOR` | DONE | |
|
||||
| `$FF8D` | `$FD1A` | `VECTOR` | DONE | |
|
||||
| `$FF90` | | `SETMSG` | DONE | |
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define CONFIG_IEC
|
||||
// #define CONFIG_IEC_JIFFYDOS // 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_UP9600 // please keep disabled for now
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define CONFIG_IEC
|
||||
// #define CONFIG_IEC_JIFFYDOS // 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_UP9600 // please keep disabled for now
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#define CONFIG_IEC
|
||||
// #define CONFIG_IEC_JIFFYDOS // 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_UP9600 // please keep disabled for now
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define CONFIG_IEC
|
||||
// #define CONFIG_IEC_JIFFYDOS // 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_UP9600 // please keep disabled for now
|
||||
|
||||
|
||||
@@ -299,8 +299,6 @@
|
||||
.eval features_str = ADD_FEATURE(features_str, "TAPE NORMAL+TURBO")
|
||||
#endif
|
||||
|
||||
.eval feature_new_line = true
|
||||
|
||||
#if CONFIG_IEC
|
||||
.eval features_str = ADD_FEATURE(features_str, "IEC")
|
||||
#endif
|
||||
|
||||
@@ -10,12 +10,9 @@ hw_entry_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
|
||||
|
||||
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
|
||||
|
||||
dex // $FF - to initialize stack pointer
|
||||
ldx #$FF
|
||||
txs
|
||||
|
||||
// The following routine is based on reading the public KERNAL jumptable routine
|
||||
@@ -28,6 +25,10 @@ hw_entry_reset:
|
||||
bne !+
|
||||
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.
|
||||
jsr JIOINIT
|
||||
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
ramtas_real:
|
||||
RAMTAS:
|
||||
|
||||
// C64 Programmer's Reference guide p291:
|
||||
// Clear $0000-$0101, $0200-$03ff
|
||||
// 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
|
||||
// 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 longer sequence of identicale bytes we see no basis for
|
||||
// it being copyrightable. Again, we just want to redue the attack
|
||||
// surface for any misguided suit.
|
||||
|
||||
ldy #$00
|
||||
lda #$00
|
||||
!:
|
||||
sta $0300,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
|
||||
bne !-
|
||||
|
||||
// Allocate cassette buffer
|
||||
// "Mapping the C64", p237
|
||||
lda #<$033C
|
||||
sta TAPE1+0
|
||||
lda #>$033C
|
||||
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
|
||||
ldx #<$033C
|
||||
stx TAPE1+0
|
||||
ldx #>$033C
|
||||
stx TAPE1+1
|
||||
|
||||
// Set screen address pointer ("Compute's Mapping the 64" p238)
|
||||
// This is obvious boiler plate containing no creative input, but to avoid
|
||||
@@ -62,30 +43,41 @@ ramtas_real:
|
||||
ldx #>$0400
|
||||
stx HIBASE
|
||||
|
||||
// Work out RAM size and put in MEMSTR and MEMSIZK
|
||||
// "Compute's Mapping the 64", p54
|
||||
// http://unusedino.de/ec64/technical/project64/mapping_c64.html
|
||||
// Set BASIC start text pointer
|
||||
// (remember, that low memory is 0 initialized at this moment)
|
||||
|
||||
ldx #>$0800
|
||||
stx MEMSTR+1
|
||||
ldx #$00
|
||||
stx MEMSTR+0
|
||||
stx MEMSIZK+0
|
||||
|
||||
// Work out RAM size and put in MEMSIZK
|
||||
// Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF
|
||||
|
||||
ldx $8000
|
||||
inx
|
||||
stx $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
|
||||
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
|
||||
|
||||
ramtas_32k:
|
||||
|
||||
// 32K RAM - restore memory content, set MEMSIZK
|
||||
|
||||
ldy #$80
|
||||
bne !- // branch always
|
||||
@@ -11,39 +11,71 @@
|
||||
|
||||
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
|
||||
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
// Work around for VICE bug: Writing $00 before $01 results in rubbish in $01
|
||||
// after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
||||
|
||||
lda #$27
|
||||
ldx #$27
|
||||
stx CPU_R6510
|
||||
ldx #$EF
|
||||
sta CPU_R6510
|
||||
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
|
||||
lda SID_SIGVOL
|
||||
and #$F0
|
||||
sta SID_SIGVOL
|
||||
#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
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
|
||||
#if CONFIG_SID_D4XX
|
||||
lda SID_SIGVOL, Y
|
||||
and #$F0
|
||||
sta SID_SIGVOL, Y
|
||||
sta SID_SIGVOL + $000, Y
|
||||
#endif // CONFIG_SID_D4XX
|
||||
|
||||
#if CONFIG_SID_D5XX
|
||||
// SIDs under $D5xx
|
||||
lda SID_SIGVOL + $100, Y
|
||||
and #$F0
|
||||
sta SID_SIGVOL + $100, Y
|
||||
#endif // CONFIG_SID_D4XX
|
||||
|
||||
@@ -52,50 +84,20 @@ IOINIT:
|
||||
adc #$20
|
||||
tay
|
||||
bne !-
|
||||
|
||||
#endif // CONFIG_SID_D4XX || CONFIG_SID_D5XX
|
||||
|
||||
#if CONFIG_SID_2ND
|
||||
lda SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
|
||||
and #$F0
|
||||
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
|
||||
#endif // CONFIG_SID_2ND
|
||||
//
|
||||
// Now continue the CIAs initialization
|
||||
//
|
||||
|
||||
#if CONFIG_SID_3RD
|
||||
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
|
||||
// For CIA #1 we need port A as output and port B as input to scan the keyboard
|
||||
|
||||
ldx #$FF
|
||||
stx CIA1_DDRA // output
|
||||
inx // $00
|
||||
stx CIA1_DDRB // input
|
||||
|
||||
// Value checked on original ROM
|
||||
stx CIA2_DDRA
|
||||
stx CIA1_DDRA // $DC02
|
||||
inx
|
||||
stx CIA1_DDRB // $DC03
|
||||
stx CIA2_DDRB // $DD03 // XXX this port is used for RS-232, value here is most likely wrong!
|
||||
|
||||
#if CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK
|
||||
|
||||
@@ -104,13 +106,38 @@ IOINIT:
|
||||
|
||||
#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
|
||||
sta CIA2_DDRA
|
||||
sta CIA2_DDRA // $DD02
|
||||
|
||||
// Set VIC-II bank - needed at least for 'Operacja Proboszcz' game
|
||||
lda #%00000011
|
||||
sta CIA2_PRA
|
||||
// XXX detect TOD clock, see https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ setup_pal:
|
||||
// ldx #>16380
|
||||
|
||||
// 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
|
||||
ldx #>16421
|
||||
@@ -43,8 +43,8 @@ setup_pal:
|
||||
|
||||
setup_pal_ntsc_end:
|
||||
|
||||
sty CIA1_TIMALO
|
||||
stx CIA1_TIMAHI
|
||||
sty CIA1_TIMALO // $DC04
|
||||
stx CIA1_TIMAHI // $DC05
|
||||
|
||||
sta TVSFLG
|
||||
|
||||
@@ -55,7 +55,7 @@ setup_ntsc:
|
||||
// Set timer interval to ~1/60th of a second
|
||||
|
||||
// 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
|
||||
ldx #>17045
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
load_tape_turbo:
|
||||
|
||||
// XXX prepare SID, store screen color somewhere, read header
|
||||
|
||||
jsr tape_ditch_verify // only LOAD is supported, no VERIFY
|
||||
|
||||
ldy #$00
|
||||
@@ -91,16 +93,24 @@ tape_turbo_get_bit:
|
||||
|
||||
lda #$10
|
||||
!:
|
||||
bit CIA2_ICR
|
||||
bit CIA1_ICR
|
||||
beq !- // busy loop to detect signal
|
||||
lda CIA2_ICR
|
||||
pha
|
||||
lda #$19
|
||||
sta CIA2_CRA
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ tape_ask_play:
|
||||
ldx #__MSG_KERNAL_PRESS_PLAY
|
||||
jsr print_kernal_message
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
tape_wait_button_loop:
|
||||
|
||||
jsr udtim_keyboard
|
||||
@@ -71,7 +73,8 @@ tape_load_success:
|
||||
|
||||
jsr screen_show
|
||||
jsr tape_motor_off
|
||||
|
||||
|
||||
cli
|
||||
jmp lvs_success_end
|
||||
|
||||
|
||||
@@ -80,6 +83,7 @@ tape_load_error:
|
||||
jsr screen_show
|
||||
jsr tape_motor_off
|
||||
|
||||
cli
|
||||
jmp lvs_load_verify_error
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user