From 37c86a33d1d5a849d18b8abbfd1427340bd306b6 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 19 Jan 2020 20:59:59 +0100 Subject: [PATCH 01/66] work towards tape speed calibration in normal system load --- c64/aliases/,aliases_ram_lowmem.s | 30 ++++++-- c64/kernal/iostack/f4a5.load.s | 15 +++- c64/kernal/tape/load_tape_normal.s | 24 ++---- c64/kernal/tape/load_tape_turbo.s | 8 ++ c64/kernal/tape/tape_common_autodetect.s | 4 +- c64/kernal/tape/tape_common_get_pulse.s | 33 ++++++++ c64/kernal/tape/tape_common_prepare_cia.s | 2 +- c64/kernal/tape/tape_normal_calibrate.s | 86 +++++++++++++++++++++ c64/kernal/tape/tape_normal_get_bit.s | 16 +++- c64/kernal/tape/tape_normal_get_marker.s | 39 ++++++++-- c64/kernal/tape/tape_normal_get_pilot.s | 93 +++++++++++++++++++++++ c64/kernal/tape/tape_normal_get_pulse.s | 44 ----------- c64/kernal/tape/tape_normal_pilot.s | 78 ------------------- c64/kernal/tape/tape_normal_sync.s | 2 +- c64/kernal/tape/tape_turbo_get_bit.s | 22 +----- c64/kernal/tape/tape_turbo_get_byte.s | 14 ++-- c64/kernal/tape/tape_turbo_sync.s | 2 +- 17 files changed, 325 insertions(+), 187 deletions(-) create mode 100644 c64/kernal/tape/tape_common_get_pulse.s create mode 100644 c64/kernal/tape/tape_normal_calibrate.s create mode 100644 c64/kernal/tape/tape_normal_get_pilot.s delete mode 100644 c64/kernal/tape/tape_normal_get_pulse.s delete mode 100644 c64/kernal/tape/tape_normal_pilot.s diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 4e6d2593..56a5b24e 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -1,6 +1,6 @@ // // Names of ZP and low memory locations: -// - Compute's Mapping the Commodore 64 +// - Computes Mapping the Commodore 64 // - https://www.c64-wiki.com/wiki/Zeropage // - http://unusedino.de/ec64/technical/project64/memory_maps.html // @@ -83,8 +83,8 @@ // .label IOSTATUS = $90 - .label STKEY = $91 // Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2 - .label SVXT = $92 // -- NOT IMPLEMENTED -- + .label STKEY = $91 // keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2 + .label SVXT = $92 // tape reading constant [!] our tape routines use it differently .label VERCKK = $93 // 0 = LOAD, 1 = VERIFY .label C3PO = $94 // flag - is BSOUR content valid .label BSOUR = $95 // serial bus buffered output byte @@ -118,8 +118,8 @@ .label RIDDATA = $AA // -- NOT IMPLEMENTED -- .label RIPRTY = $AB // -- WIP -- checksum while reading tape #endif - .label SAL = $AC // $AC-$AD -- NOT IMPLEMENTED -- (implemented screen part) - .label EAL = $AE // $AE-$AF -- NOT IMPLEMENTED -- [!] used also by screen editor, for temporary color storage when scrolling + .label SAL = $AC // $AC-$AD -- XXX: describe -- (implemented screen part) + .label EAL = $AE // $AE-$AF -- XXX: describe -- [!] used also by screen editor, for temporary color storage when scrolling .label CMP0 = $B0 // $B0-$B1 temporary tape storage, [!] here used for BRK instruction address .label TAPE1 = $B2 // $B2-$B3 tape buffer pointer #if !CONFIG_LEGACY_SCNKEY @@ -227,7 +227,7 @@ #if CONFIG_MEMORY_MODEL_60K // IRQs are disabled when doing such accesses, and a default NMI handler only increments - // a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured. + // a counter, so that if an NMI occurs, it does not crash the machine, but can be captured. .label missed_nmi_flag = $2A7 .label tiny_nmi_handler = $2A8 @@ -288,3 +288,21 @@ #endif // $3FC $3FC-$3FF -- UNUSED -- free for user software + + +// +// Definitions foor tape functionality +// + +#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO + + .label __normal_time_S = IRQTMP+0 // duration of the short pulse + .label __normal_time_M = IRQTMP+1 // duration of the medium pulse + + .label __turbo_half_S = IRQTMP+0 // half-duration of the short pulse + .label __turbo_half_L = IRQTMP+1 // half-duration of the long pulse + + .label __pulse_threshold = SVXT // pulse classification threshold + .label __pulse_threshold_ML = SYNO // M/L pulse classification threshold, for normal only + +#endif diff --git a/c64/kernal/iostack/f4a5.load.s b/c64/kernal/iostack/f4a5.load.s index 7c39a23e..ac201c15 100644 --- a/c64/kernal/iostack/f4a5.load.s +++ b/c64/kernal/iostack/f4a5.load.s @@ -43,19 +43,32 @@ LOAD: // Check whether we support the requested device lda FA + +#if !CONFIG_TAPE_AUTODETECT + #if CONFIG_TAPE_NORMAL cmp #$01 beq_16 load_tape_normal #endif - #if CONFIG_TAPE_TURBO cmp #$07 beq_16 load_tape_turbo #endif +#else // CONFIG_TAPE_AUTODETECT + + cmp #$01 + beq_16 load_tape_auto + cmp #$07 + beq_16 load_tape_auto + +#endif + + #if CONFIG_IEC jsr iec_check_devnum_lvs bcc_16 load_iec #endif + jmp lvs_illegal_device_number diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index f1ae13fa..4ffd0b2f 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -33,37 +33,27 @@ // (L,S) = end-of-data marker -// XXX use pilot to calibrate reading speed // XXX add error correction +// XXX implement proper takeover to turbo during sync/pilot #if CONFIG_TAPE_NORMAL +#if !CONFIG_TAPE_AUTODETECT + load_tape_normal: jsr tape_ditch_verify // only LOAD is supported, no VERIFY -#if CONFIG_TAPE_AUTODETECT - - // Prepare for sound effects in case of turbo takeover - jsr tape_clean_sid - -#endif - // Start playing jsr tape_common_prepare_cia jsr tape_ask_play -#if CONFIG_TAPE_AUTODETECT - - // FALLTROUGH +#else load_tape_normal_takeover: // entry point for turbo->normal takeover - jsr tape_common_autodetect - bcs_16 load_tape_turbo_takeover - #endif // Temporarily store MEMUSS in EAL @@ -86,10 +76,10 @@ load_tape_normal_header: // Retrieve the header - jsr tape_normal_pilot_header + jsr tape_normal_get_pilot_header ldy #$C1 // size limit (including checksum) jsr tape_normal_get_data - bcs load_tape_normal_header // unable to read block, try again + bcs load_tape_normal_header // unable to read block, try again XXX restore MEMUSS and jump to turbo detection // Check header type @@ -127,7 +117,7 @@ load_tape_normal_payload: // Retrieve data - jsr tape_normal_pilot_data + jsr tape_normal_get_pilot_data ldy #$00 // no data size limit jsr tape_normal_get_data bcs_16 tape_load_error diff --git a/c64/kernal/tape/load_tape_turbo.s b/c64/kernal/tape/load_tape_turbo.s index fa470180..7f8a3d9d 100644 --- a/c64/kernal/tape/load_tape_turbo.s +++ b/c64/kernal/tape/load_tape_turbo.s @@ -14,8 +14,16 @@ #if CONFIG_TAPE_TURBO +#if !CONFIG_TAPE_AUTODETECT + load_tape_turbo: +#else + +load_tape_auto: + +#endif + jsr tape_ditch_verify // only LOAD is supported, no VERIFY // Prepare for sound effects diff --git a/c64/kernal/tape/tape_common_autodetect.s b/c64/kernal/tape/tape_common_autodetect.s index 86fefe92..7ce2b048 100644 --- a/c64/kernal/tape/tape_common_autodetect.s +++ b/c64/kernal/tape/tape_common_autodetect.s @@ -38,13 +38,13 @@ tape_common_autodetect_retry: sta XSAV ldy #$60 // $60 pulses cover 12 bytes of turbo recording - jsr tape_normal_get_pulse // first pulse might be a garbage, ignore it + jsr tape_common_get_pulse // first pulse might be a garbage, ignore it // FALLTROUGH tape_common_autodetect_loop: - jsr tape_normal_get_pulse // read pulse for detection attempt + jsr tape_common_get_pulse // read pulse for detection attempt // If garbage found, retry detection cmp #$28 diff --git a/c64/kernal/tape/tape_common_get_pulse.s b/c64/kernal/tape/tape_common_get_pulse.s new file mode 100644 index 00000000..dfbba663 --- /dev/null +++ b/c64/kernal/tape/tape_common_get_pulse.s @@ -0,0 +1,33 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape helper routine - pulse reading +// +// Returns pulse length (with a bias, see comments) in .A +// + + +#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO + + +tape_common_get_pulse: + + // Contrary to original ROM implementation we do not use interrupts + // (see http://unusedino.de/ec64/technical/formats/tap.html) - busy wait + // implementation is probably just shorter + + lda #$10 +!: + bit CIA1_ICR // $DC0D + beq !- // busy loop to detect signal, restart timer afterwards + lda CIA2_TIMBLO // $DD06 + ldx #%01010001 // start timer, force latch reload, count timer A underflows + stx CIA2_CRB // $DD0F + + cmp __pulse_threshold // sdefault pulse check + rts + + +#endif diff --git a/c64/kernal/tape/tape_common_prepare_cia.s b/c64/kernal/tape/tape_common_prepare_cia.s index 0fda0555..ce172a03 100644 --- a/c64/kernal/tape/tape_common_prepare_cia.s +++ b/c64/kernal/tape/tape_common_prepare_cia.s @@ -7,7 +7,7 @@ // // -// Checked under VICE, PAL, average of 256 pulses: XXX retry measurements for NORMAL, something is probably wrong +// Checked under VICE, PAL, average of 256 pulses: // // normal - short - timer goes down to $A5 // normal - medium - timer goes down to $7D diff --git a/c64/kernal/tape/tape_normal_calibrate.s b/c64/kernal/tape/tape_normal_calibrate.s new file mode 100644 index 00000000..d5274d2c --- /dev/null +++ b/c64/kernal/tape/tape_normal_calibrate.s @@ -0,0 +1,86 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (normal) helper routine - reading speed calibration +// +// Needs pulse length in .A +// + + +#if CONFIG_TAPE_NORMAL + + +tape_normal_calibrate_during_pilot: // reecalibration during the pilot + + sta __normal_time_S + + // We do not have any recent medium pulse measurement, + // probably the only solution is to estimate it + + lda $FF + sec + sbc __normal_time_S + + // We now have a difference from the starting point ($FF) + + clc + rol + sta __normal_time_M // this is temporary only! + + // We now have half the difference, substract it from + // short pulse measurement result + + lda __normal_time_S + clc + sbc __normal_time_M + + // XXX add some constant to get a proper __normal_time_M ($7D if starting from $A5), afterwards remove __normal_time_M initialization from tape_normal_get_pilot_header + + sta __normal_time_M + + jmp tape_normal_calibrate_common + + +tape_normal_calibrate_after_S: // recalibration after short pulse + + sta __normal_time_S + rts + skip_2_bytes_trash_nvz + + // FALLTROUGH + +tape_normal_calibrate_after_M: // recalibration after medium pulse + + sta __normal_time_M + + // FALLTROUGH + +tape_normal_calibrate_common: + + // Now compare results with current threshold + + lda __normal_time_S + sec + sbc __pulse_threshold + clc + adc __normal_time_M + + cmp __pulse_threshold + beq tape_normal_calibrate_done // branch if no recalibration needed + + + + // XXX implement recalibration + + + + + +tape_normal_calibrate_done: + + rts + + +#endif diff --git a/c64/kernal/tape/tape_normal_get_bit.s b/c64/kernal/tape/tape_normal_get_bit.s index a092daa1..960f92ee 100644 --- a/c64/kernal/tape/tape_normal_get_bit.s +++ b/c64/kernal/tape/tape_normal_get_bit.s @@ -16,17 +16,20 @@ tape_normal_get_bit: // Fetch the first pulse - jsr tape_normal_get_pulse + jsr tape_common_get_pulse bcc tape_normal_get_bit_1 // First impulse was short, second should be medium - jsr tape_normal_get_pulse + jsr tape_normal_calibrate_after_S + + jsr tape_common_get_pulse bcs tape_normal_get_bit_error + jsr tape_normal_calibrate_after_M + // We have a bit '0' - // Carry flag already clear lda #$00 // FALLTROUGH @@ -34,6 +37,7 @@ tape_normal_get_bit: tape_normal_get_bit_done: sta VIC_EXTCOL + clc rts @@ -41,9 +45,13 @@ tape_normal_get_bit_1: // First impulse was medium, second should be short - jsr tape_normal_get_pulse + jsr tape_normal_calibrate_after_M + + jsr tape_common_get_pulse bcc tape_normal_get_bit_error + jsr tape_normal_calibrate_after_S + // We have a bit '1' clc diff --git a/c64/kernal/tape/tape_normal_get_marker.s b/c64/kernal/tape/tape_normal_get_marker.s index 4106214c..bab658f7 100644 --- a/c64/kernal/tape/tape_normal_get_marker.s +++ b/c64/kernal/tape/tape_normal_get_marker.s @@ -5,22 +5,49 @@ // // Tape (normal) helper routine - marker reading // -// Reeturns marker type in Carry flag, set = end of data +// Reeturns marker type in Carry flag, set = end of data (normal marker) or failure (marker while sync) // #if CONFIG_TAPE_NORMAL + // (L,M) - end of byte, (L,S) - end of data -tape_normal_get_marker: + +tape_normal_get_marker: + + + jsr tape_common_get_pulse + cmp __pulse_threshold_ML + bcs tape_normal_get_marker // too short for a long pulse + + // FALLTROUGH + +tape_normal_get_marker_type: + + jmp tape_common_get_pulse + + + +!: // Not an entry point!!! + + // XXX check for short pulses of turbo here + + jsr tape_normal_calibrate_during_pilot // while sync use short pulses for calibration + + // FALLTROUGH + +tape_normal_get_marker_while_sync: // (L,M) - end of byte, (L,S) - end of data - jsr tape_normal_get_pulse - cmp #($FF - $98 - $04) - bcs tape_normal_get_marker // too short for a long pulse + jsr tape_common_get_pulse + bcs !- // branch if short pulse - jmp tape_normal_get_pulse + cmp __pulse_threshold_ML + bcs tape_normal_get_marker_while_sync // too short for a long pulse + + bcc tape_normal_get_marker_type // branch always #endif diff --git a/c64/kernal/tape/tape_normal_get_pilot.s b/c64/kernal/tape/tape_normal_get_pilot.s new file mode 100644 index 00000000..11c17c0b --- /dev/null +++ b/c64/kernal/tape/tape_normal_get_pilot.s @@ -0,0 +1,93 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (turbo) helper routine - handling the pilot +// + +// Injest the pilot - series of short pulses. According to http://sidpreservation.6581.org/tape-format/ +// it consist of the following number of pulses: +// - $6A00 for header +// - $1A00 for data and seq block header +// - $4F for repeated header/data + + +#if CONFIG_TAPE_NORMAL + + +// XXX in tape_normal_get_pilot_header also try to detect turbo + +tape_normal_get_pilot_header: // entry point, reset calibration, require 128x $40 pulses + + // Reading the pilot header is the first action performed, + // thus start by setting default timings, as measured during + // VICE test + + lda #$7D + sta __normal_time_M // __normal_time_S will be set within the pilot + lda #$91 + sta __pulse_threshold + lda #$67 + sta __pulse_threshold_ML + + lda #$80 + + skip_2_bytes_trash_nvz + + // FALLTROUGH + +tape_normal_get_pilot_data: // entry point, require 4x $40 pulses + + lda #$04 + + skip_2_bytes_trash_nvz + + // FALLTROUGH + +tape_normal_get_pilot_short: // entry point, require 1x $40 pulses + + lda #$01 + + // FALLTROUGH + +tape_normal_get_pilot_common: + + sta FSBLK + + lda #$0B + sta VIC_EXTCOL + + // FALLTROUGH + +tape_normal_get_pilot_common_restart: + + lda FSBLK + sta ROPRTY + + // FALLTROUGH + +tape_normal_get_pilot_common_loop_outer: + + ldy #$40 + + // FALLTROUGH + +tape_normal_get_pilot_common_loop_inner: + + jsr tape_common_get_pulse + // XXX check for short pulses of turbo here + bcc tape_normal_get_pilot_common_restart // not a pilot - try again + + jsr tape_normal_calibrate_during_pilot + + dey + bne tape_normal_get_pilot_common_loop_inner + + dec ROPRTY + bne tape_normal_get_pilot_common_loop_outer + + rts + + +#endif diff --git a/c64/kernal/tape/tape_normal_get_pulse.s b/c64/kernal/tape/tape_normal_get_pulse.s deleted file mode 100644 index ac4a1f02..00000000 --- a/c64/kernal/tape/tape_normal_get_pulse.s +++ /dev/null @@ -1,44 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Tape (normal) helper routine - pulse reading -// -// Returns pulse length (with a bias, see comments) in .A -// - - -#if CONFIG_TAPE_NORMAL - - -tape_normal_get_pulse: - - // Contrary to original ROM implementation we do not use interrupts - // (see http://unusedino.de/ec64/technical/formats/tap.html) - busy wait - // implementation is probably just shorter - - lda #$10 -!: - bit CIA1_ICR // $DC0D - beq !- // busy loop to detect signal, restart timer afterwards - lda CIA2_TIMBLO // $DD06 - ldx #%01010001 // start timer, force latch reload, count timer A underflows - stx CIA2_CRB // $DD0F - - // Since the signal appeared to the point of timer restart we used: - // bit - 4 cycles - // beq - 2 cycles - // lda - 4 cycles - // ldx - 2 cycles - // stx - 4 cycles - // plus average 3 cycles (bit + beq time divided by 2) from value change to 'bit' instruction - // minus average 2 cycles due to timer A running continouslyy (might start before the pulse) - // this is total 17 cycles, or $4 periods of 4 ticks (timer A) each - we need to take it into account - // every time we check the pulse length - - cmp #($FF - $72 - $04) // short vs medium is the default check - rts - - -#endif diff --git a/c64/kernal/tape/tape_normal_pilot.s b/c64/kernal/tape/tape_normal_pilot.s deleted file mode 100644 index 0ea7dff7..00000000 --- a/c64/kernal/tape/tape_normal_pilot.s +++ /dev/null @@ -1,78 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Tape (turbo) helper routine - handling the pilot -// - -// Injest the pilot - series of short pulses. According to http://sidpreservation.6581.org/tape-format/ -// it consist of the following number of pulses: -// - $6A00 for header -// - $1A00 for data and seq block header -// - $4F for repeated header/data - - -#if CONFIG_TAPE_NORMAL - - - -tape_normal_pilot_short: // require 1x $40 pulses - - lda #$01 - - // FALLTROUGH - -tape_normal_pilot_common: - - sta FSBLK - - // FALLTROUGH - -tape_normal_pilot_common_restart: - - lda #$0B - sta VIC_EXTCOL - - lda FSBLK - sta ROPRTY - - // FALLTROUGH - -tape_normal_pilot_common_loop_outer: - - ldy #$40 - - // FALLTROUGH - -tape_normal_pilot_common_loop_inner: - - jsr tape_normal_get_pulse - bcc tape_normal_pilot_common_restart // not a pilot - try again - - dey - bne tape_normal_pilot_common_loop_inner - - dec ROPRTY - bne tape_normal_pilot_common_loop_outer - - rts - - - -tape_normal_pilot_data: // require 4x $40 pulses - - lda #$04 - - skip_2_bytes_trash_nvz - - // FALLTROUGH - -tape_normal_pilot_header: // require 128x $40 pulses - - lda #$80 - - jmp tape_normal_pilot_common // XXX calibrate tape speed afterwards - - -#endif diff --git a/c64/kernal/tape/tape_normal_sync.s b/c64/kernal/tape/tape_normal_sync.s index 65310ab8..5fbd5779 100644 --- a/c64/kernal/tape/tape_normal_sync.s +++ b/c64/kernal/tape/tape_normal_sync.s @@ -19,7 +19,7 @@ tape_normal_sync: // Injest bytes of decreasing values - jsr tape_normal_get_marker + jsr tape_normal_get_marker_while_sync bcs tape_normal_sync_fail // branch if end of data marker jsr tape_normal_get_byte diff --git a/c64/kernal/tape/tape_turbo_get_bit.s b/c64/kernal/tape/tape_turbo_get_bit.s index e636772a..eaf5be4e 100644 --- a/c64/kernal/tape/tape_turbo_get_bit.s +++ b/c64/kernal/tape/tape_turbo_get_bit.s @@ -14,29 +14,13 @@ tape_turbo_get_bit: - -#if CONFIG_TAPE_NORMAL - jsr tape_normal_get_pulse // reuse routine from NORMAL system - -#else - - lda #$10 -!: - bit CIA1_ICR // $DC0D - beq !- // busy loop to detect signal, restart timer afterwards - lda CIA2_TIMBLO // $DD06 - ldx #%01010001 // start timer, force latch reload, count timer A underflows - stx CIA2_CRB // $DD0F - -#endif - - cmp SYNO // threshold + jsr tape_common_get_pulse bcs !+ clc ror - sta IRQTMP+0 // store half of the last measurement result for short pulse + sta __turbo_half_S // store half of the last measurement result for short pulse lda #$01 sta SID_SIGVOL @@ -47,7 +31,7 @@ tape_turbo_get_bit: !: clc ror - sta IRQTMP+1 // store half of the last measurement result for long pulse + sta __turbo_half_L // store half of the last measurement result for long pulse lda #$00 sta SID_SIGVOL diff --git a/c64/kernal/tape/tape_turbo_get_byte.s b/c64/kernal/tape/tape_turbo_get_byte.s index 7dfe6d66..01f76f40 100644 --- a/c64/kernal/tape/tape_turbo_get_byte.s +++ b/c64/kernal/tape/tape_turbo_get_byte.s @@ -28,28 +28,28 @@ tape_turbo_get_byte: // Compensate for tape speed variations - lda IRQTMP+0 // half of the last value for bit '0' + lda __turbo_half_S // half of the last value for bit '0' clc - adc IRQTMP+1 // half of the last value for bit '1' + adc __turbo_half_L // half of the last value for bit '1' sec - sbc SYNO // now we have a diff between current threshold and calculated one + sbc __pulse_threshold // now we have a diff between current threshold and calculated one beq tape_turbo_get_byte_done // branch if threshold correction not needed bpl !+ - lda SYNO + lda __pulse_threshold cmp #($BF - 10) beq tape_turbo_get_byte_done // do not decrease threshold too far no matter what - dec SYNO + dec __pulse_threshold bne tape_turbo_get_byte_done // branch always !: - lda SYNO + lda __pulse_threshold cmp #($BF + 10) beq tape_turbo_get_byte_done // do not increase threshold too far no matter what - inc SYNO + inc __pulse_threshold tape_turbo_get_byte_done: diff --git a/c64/kernal/tape/tape_turbo_sync.s b/c64/kernal/tape/tape_turbo_sync.s index d283c733..a20c94da 100644 --- a/c64/kernal/tape/tape_turbo_sync.s +++ b/c64/kernal/tape/tape_turbo_sync.s @@ -17,7 +17,7 @@ tape_turbo_sync_header: // Initial pulse threshold lda #$BF // measured 128 bits '0' and 128 bits '1' under VICE, calculated average - sta SYNO + sta __pulse_threshold // Synchronize with start of sync sequence jsr tape_turbo_sync_first From e9b9767a71b1177109e9a78c0d3c70ebea1e5b2d Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 20 Jan 2020 21:13:22 +0100 Subject: [PATCH 02/66] tape speed adjustments for normal load works now --- c64/kernal/tape/tape_normal_calibrate.s | 64 ++++++++++++++++++++----- c64/kernal/tape/tape_normal_get_pilot.s | 7 +-- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/c64/kernal/tape/tape_normal_calibrate.s b/c64/kernal/tape/tape_normal_calibrate.s index d5274d2c..5a517018 100644 --- a/c64/kernal/tape/tape_normal_calibrate.s +++ b/c64/kernal/tape/tape_normal_calibrate.s @@ -12,38 +12,42 @@ #if CONFIG_TAPE_NORMAL -tape_normal_calibrate_during_pilot: // reecalibration during the pilot +tape_normal_calibrate_during_pilot: // reecalibration during the pilot sta __normal_time_S // We do not have any recent medium pulse measurement, // probably the only solution is to estimate it - lda $FF + lda #$FF sec sbc __normal_time_S // We now have a difference from the starting point ($FF) clc - rol - sta __normal_time_M // this is temporary only! + ror + sta __normal_time_M // this is temporary only! // We now have half the difference, substract it from // short pulse measurement result lda __normal_time_S - clc + sec sbc __normal_time_M + + // Add a small correction to gain $7D if starting from $A5. Dirty, ugly, + // and imprecise hack - but in real life should be good enough - // XXX add some constant to get a proper __normal_time_M ($7D if starting from $A5), afterwards remove __normal_time_M initialization from tape_normal_get_pilot_header - - sta __normal_time_M + clc + adc #$05 + sta __normal_time_M // estimated medium pulse length jmp tape_normal_calibrate_common -tape_normal_calibrate_after_S: // recalibration after short pulse + +tape_normal_calibrate_after_S: // recalibration after short pulse sta __normal_time_S rts @@ -51,7 +55,7 @@ tape_normal_calibrate_after_S: // recalibration after short pulse // FALLTROUGH -tape_normal_calibrate_after_M: // recalibration after medium pulse +tape_normal_calibrate_after_M: // recalibration after medium pulse sta __normal_time_M @@ -68,14 +72,50 @@ tape_normal_calibrate_common: adc __normal_time_M cmp __pulse_threshold - beq tape_normal_calibrate_done // branch if no recalibration needed + + beq tape_normal_calibrate_done // branch if no recalibration needed + + // Correct the thresholds (default is $91 for the S/M one) + + bcs tape_normal_calibrate_threshold_inc // branch if .A >= memory + + // FALLTROUGH +tape_normal_calibrate_threshold_dec: - // XXX implement recalibration + lda __pulse_threshold + cmp #($91-10) + bcc tape_normal_calibrate_done // do not decrement thresholds too far + + sec + sbc #$02 + sta __pulse_threshold + + lda __pulse_threshold_ML + sec + sbc #$03 + sta __pulse_threshold_ML + + bne tape_normal_calibrate_done // branch always +tape_normal_calibrate_threshold_inc: + lda __pulse_threshold + cmp #($91+11) + bcs tape_normal_calibrate_done // do not increment thresholds too far + + clc + adc #$02 + sta __pulse_threshold + + lda __pulse_threshold_ML + clc + adc #$03 + sta __pulse_threshold_ML + + // FALLTROUGH tape_normal_calibrate_done: diff --git a/c64/kernal/tape/tape_normal_get_pilot.s b/c64/kernal/tape/tape_normal_get_pilot.s index 11c17c0b..801a2fb1 100644 --- a/c64/kernal/tape/tape_normal_get_pilot.s +++ b/c64/kernal/tape/tape_normal_get_pilot.s @@ -21,18 +21,14 @@ tape_normal_get_pilot_header: // entry point, reset calibration, require 128x $40 pulses // Reading the pilot header is the first action performed, - // thus start by setting default timings, as measured during - // VICE test + // thus start by setting default thresholds - lda #$7D - sta __normal_time_M // __normal_time_S will be set within the pilot lda #$91 sta __pulse_threshold lda #$67 sta __pulse_threshold_ML lda #$80 - skip_2_bytes_trash_nvz // FALLTROUGH @@ -40,7 +36,6 @@ tape_normal_get_pilot_header: // entry point, reset calibration, requir tape_normal_get_pilot_data: // entry point, require 4x $40 pulses lda #$04 - skip_2_bytes_trash_nvz // FALLTROUGH From 0ff947ca1d187553572c5332f469982f1f651d91 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 21 Jan 2020 19:20:43 +0100 Subject: [PATCH 03/66] fiurst step towards reading second copy of tap[e files --- STATUS.md | 2 +- c64/aliases/,aliases_ram_lowmem.s | 4 +- c64/kernal/tape/load_tape_normal.s | 23 ++--- c64/kernal/tape/tape_normal_get_data.s | 115 ++++++++++++++++++++----- 4 files changed, 109 insertions(+), 35 deletions(-) diff --git a/STATUS.md b/STATUS.md index 80eed824..61d0306d 100644 --- a/STATUS.md +++ b/STATUS.md @@ -69,7 +69,7 @@ The following ROM features are currently missing: | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | -| normal | PARTIAL | no tape speed calibratrion, no error correction | +| normal | PARTIAL | no error correction (work in progress) | | turbo (250 blocks) | DONE | | ## IEC bus diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 56a5b24e..41aed18a 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -100,8 +100,8 @@ .label COLSTORE = $9C // [!] screen border storage for tape routines #endif .label MSGFLG = $9D // bit 6 = error messages, bit 7 = control message - .label PTR1 = $9E // -- NOT IMPLEMENTED -- - .label PTR2 = $9F // -- NOT IMPLEMENTED -- + .label PTR1 = $9E // for tape support, counter of errorneous bytes + .label PTR2 = $9F // for tape support, counter for errorneous bytes correction .label TIME = $A0 // $A0-$A2 jiffy clock #if !CONFIG_IEC_JIFFYDOS && !CONFIG_IEC_DOLPHINDOS && !CONFIG_IEC_BURST_CIA1 && !CONFIG_IEC_BURST_CIA2 && !CONFIG_IEC_BURST_SOFT .label TSFCNT = $A3 // temporary variable for tape and IEC, [!] our usage differs diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index 4ffd0b2f..32d40b8f 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -77,7 +77,6 @@ load_tape_normal_header: // Retrieve the header jsr tape_normal_get_pilot_header - ldy #$C1 // size limit (including checksum) jsr tape_normal_get_data bcs load_tape_normal_header // unable to read block, try again XXX restore MEMUSS and jump to turbo detection @@ -97,17 +96,9 @@ load_tape_normal_header: lda #$01 sta SA // this file is non-relocatable; override secondary address with 1 !: - // Handle the header - - // Restore MEMUSS - - lda EAL+1 - sta MEMUSS+1 - lda EAL+0 - sta MEMUSS+0 - - // Handle the header + // Restore MEMUSS, handle header + jsr load_tape_normal_restore_MEMUSS jsr tape_handle_header bcs load_tape_normal_header // if name does not match, look for other header @@ -128,4 +119,14 @@ load_tape_normal_payload: jmp tape_load_success +load_tape_normal_restore_MEMUSS: + + lda EAL+1 + sta MEMUSS+1 + lda EAL+0 + sta MEMUSS+0 + + rts + + #endif diff --git a/c64/kernal/tape/tape_normal_get_data.s b/c64/kernal/tape/tape_normal_get_data.s index 780c85ac..ea7e811e 100644 --- a/c64/kernal/tape/tape_normal_get_data.s +++ b/c64/kernal/tape/tape_normal_get_data.s @@ -17,33 +17,73 @@ tape_normal_get_data: - // Store block size limit - sty XSAV - // Initialize checksum (RIPRTY, see http://sta.c64.org/cbm64mem.html) + // and pointers for error log and correction mechanism lda #$00 sta RIPRTY + sta PTR1 + sta PTR2 + + // FALLTROUGH + +tape_normal_get_data_block_1: + + // + // Read the 1st copy of the block + // // Read sync of the block ldy #$89 jsr tape_normal_sync - bcs tape_normal_get_block_done + bcs tape_normal_get_data_fail jsr tape_normal_get_marker -tape_normal_get_data_loop: +tape_normal_get_data_loop_1: jsr tape_normal_get_byte - bcs tape_normal_get_block_done // error reading byte - fatal for now - jsr tape_normal_get_marker - bcs tape_normal_get_checksum // end of data for the block + bcc tape_normal_get_data_loop_1_byte_OK + + // Problem reading a byte, try to add it to the error log + tsx + cpx #$20 // just to be on a safe side + bcc tape_normal_get_data_fail // branch if no more space in error log + + ldx PTR1 + lda MEMUSS+0 + sta STACK, x + inx + lda MEMUSS+1 + sta STACK, x + inx + sta PTR1 + + // Addres added to error log, check if this was a checksum + jsr tape_normal_get_marker + bcc tape_normal_get_data_loop_1_advance + bcs tape_normal_get_data_block_2 + + +tape_normal_get_data_loop_1_byte_OK: + + jsr tape_normal_get_marker + bcc !+ + + // End of the block + jsr tape_normal_update_checksum + jmp tape_normal_get_data_block_2 + +!: // Store byte, calculate checksum lda INBIT ldy #$00 sta (MEMUSS), y - eor RIPRTY - sta RIPRTY + jsr tape_normal_update_checksum + // FALLTROUGH + +tape_normal_get_data_loop_1_advance: + // Advance pointer #if !HAS_OPCODES_65CE02 jsr lvs_advance_MEMUSS @@ -51,26 +91,59 @@ tape_normal_get_data_loop: inw MEMUSS+0 #endif - // Check block length limit - lda XSAV - beq tape_normal_get_data_loop // no limit requested - dec XSAV - bne tape_normal_get_data_loop + jmp tape_normal_get_data_loop_1 - sec - rts -tape_normal_get_checksum: // XXX handle second copy, with pilot starting from $09 +tape_normal_get_data_block_2: - lda INBIT - eor RIPRTY + // + // Read the 2nd copy of the block + // + + // First check if there is a need to read anything + + // XXX + + // Read sync of the block + ldy #$09 + jsr tape_normal_sync + bcs tape_normal_get_data_fail + jsr tape_normal_get_marker + + // XXX implement the second pass + + + lda PTR1 + beq tape_normal_get_data_checksum + + jmp tape_normal_get_data_fail + + + + +tape_normal_get_data_checksum: + + lda RIPRTY cmp #$01 // sets Carry if checksum verification fails // FALLTROUGH -tape_normal_get_block_done: +tape_normal_get_data_done: rts +tape_normal_get_data_fail: + + sec + rts + + +tape_normal_update_checksum: + + lda INBIT + eor RIPRTY + sta RIPRTY + rts + #endif From 136cb528f750759f6d57cf12a3d66cdbb53cb857 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 22 Jan 2020 20:58:06 +0100 Subject: [PATCH 04/66] small size optimization in tape support code --- c64/,,config_custom.s | 2 +- c64/,,config_generic.s | 2 +- c64/kernal/tape/load_tape_normal.s | 21 ++---------------- c64/kernal/tape/tape_normal_get_data.s | 8 ------- c64/kernal/tape/tape_normal_update_checksum.s | 22 +++++++++++++++++++ 5 files changed, 26 insertions(+), 29 deletions(-) create mode 100644 c64/kernal/tape/tape_normal_update_checksum.s diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index 60fa3d47..22206333 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -56,7 +56,7 @@ #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO -#define CONFIG_TAPE_AUTODETECT // mostly works, but not fullyy done yet! +#define CONFIG_TAPE_AUTODETECT // mostly works, but not fully done yet! // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index 4195ef46..ef1c11d6 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -48,7 +48,7 @@ #define CONFIG_IEC_JIFFYDOS #define CONFIG_IEC_JIFFYDOS_BLANK -#define CONFIG_TAPE_NORMAL +// #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index 32d40b8f..383de31a 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -56,18 +56,11 @@ load_tape_normal_takeover: // entry point for turbo->normal takeover #endif - // Temporarily store MEMUSS in EAL - - lda MEMUSS+1 - sta EAL+1 - lda MEMUSS+0 - sta EAL+0 - // FALLTROUGH load_tape_normal_header: - // Try to load header into tape buffer + // Try to load header into tape buffer (we will restore MEMUSS later) lda TAPE1+1 sta MEMUSS+1 @@ -98,7 +91,7 @@ load_tape_normal_header: !: // Restore MEMUSS, handle header - jsr load_tape_normal_restore_MEMUSS + jsr lvs_setup_MEMUSS jsr tape_handle_header bcs load_tape_normal_header // if name does not match, look for other header @@ -119,14 +112,4 @@ load_tape_normal_payload: jmp tape_load_success -load_tape_normal_restore_MEMUSS: - - lda EAL+1 - sta MEMUSS+1 - lda EAL+0 - sta MEMUSS+0 - - rts - - #endif diff --git a/c64/kernal/tape/tape_normal_get_data.s b/c64/kernal/tape/tape_normal_get_data.s index ea7e811e..34e16f9d 100644 --- a/c64/kernal/tape/tape_normal_get_data.s +++ b/c64/kernal/tape/tape_normal_get_data.s @@ -138,12 +138,4 @@ tape_normal_get_data_fail: rts -tape_normal_update_checksum: - - lda INBIT - eor RIPRTY - sta RIPRTY - rts - - #endif diff --git a/c64/kernal/tape/tape_normal_update_checksum.s b/c64/kernal/tape/tape_normal_update_checksum.s new file mode 100644 index 00000000..d808f872 --- /dev/null +++ b/c64/kernal/tape/tape_normal_update_checksum.s @@ -0,0 +1,22 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (normal) helper routine - checksum calculation +// + + +#if CONFIG_TAPE_NORMAL + + +tape_normal_update_checksum: + + lda INBIT + eor RIPRTY + sta RIPRTY + + rts + + +#endif From 28a96a7ffc149a2cf33b1bbe3a320f638e6bb55a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 23 Jan 2020 21:35:05 +0100 Subject: [PATCH 05/66] more work towards tape error correction --- c64/kernal/tape/load_tape_normal.s | 33 +++++++--- c64/kernal/tape/tape_common.s | 2 +- ...al_get_data.s => tape_normal_get_data_1.s} | 66 +++++-------------- c64/kernal/tape/tape_normal_get_data_2.s | 51 ++++++++++++++ 4 files changed, 91 insertions(+), 61 deletions(-) rename c64/kernal/tape/{tape_normal_get_data.s => tape_normal_get_data_1.s} (56%) create mode 100644 c64/kernal/tape/tape_normal_get_data_2.s diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index 383de31a..dc5742e5 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -62,16 +62,15 @@ load_tape_normal_header: // Try to load header into tape buffer (we will restore MEMUSS later) - lda TAPE1+1 - sta MEMUSS+1 - lda TAPE1+0 - sta MEMUSS+0 - - // Retrieve the header - jsr tape_normal_get_pilot_header - jsr tape_normal_get_data - bcs load_tape_normal_header // unable to read block, try again XXX restore MEMUSS and jump to turbo detection + + jsr load_tape_normal_buf_MEMUSS + jsr tape_normal_get_data_1 + bcs load_tape_normal_header // unable to read block, try again XXX jump to turbo detection + + jsr load_tape_normal_buf_MEMUSS + jsr tape_normal_get_data_2 + bcs load_tape_normal_header // block load error, try again XXX jump to turbo detection // Check header type @@ -103,13 +102,27 @@ load_tape_normal_payload: jsr tape_normal_get_pilot_data ldy #$00 // no data size limit - jsr tape_normal_get_data + jsr tape_normal_get_data_1 bcs_16 tape_load_error jsr lvs_check_EAL bne_16 tape_load_error // amount of data read does not match header info + // XXX setup MEMUSS once again + jsr tape_normal_get_data_2 + bcs_16 tape_load_error + jmp tape_load_success +load_tape_normal_buf_MEMUSS: // set MEMUSS (start address) as tape buffer + + lda TAPE1+1 + sta MEMUSS+1 + lda TAPE1+0 + sta MEMUSS+0 + + rts + + #endif diff --git a/c64/kernal/tape/tape_common.s b/c64/kernal/tape/tape_common.s index e2461a05..136d1408 100644 --- a/c64/kernal/tape/tape_common.s +++ b/c64/kernal/tape/tape_common.s @@ -160,7 +160,7 @@ tape_handle_header: sbc STAL+1 sta EAL+1 - // STAL = MEMUSS + // STAL = MEMUSS XXX is it needed? lda MEMUSS+0 sta STAL+0 diff --git a/c64/kernal/tape/tape_normal_get_data.s b/c64/kernal/tape/tape_normal_get_data_1.s similarity index 56% rename from c64/kernal/tape/tape_normal_get_data.s rename to c64/kernal/tape/tape_normal_get_data_1.s index 34e16f9d..09ab2c7c 100644 --- a/c64/kernal/tape/tape_normal_get_data.s +++ b/c64/kernal/tape/tape_normal_get_data_1.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// Tape (normal) helper routine - data block reading +// Tape (normal) helper routine - data block (primary) reading // // Stores data starting from MEMUSS, Carry set means error, on 0 bit .A is 0 too // .Y not equal to 0 - returns error if data block is longer (length includes checksum) @@ -15,7 +15,7 @@ #if CONFIG_TAPE_NORMAL -tape_normal_get_data: +tape_normal_get_data_1: // Initialize checksum (RIPRTY, see http://sta.c64.org/cbm64mem.html) // and pointers for error log and correction mechanism @@ -26,7 +26,7 @@ tape_normal_get_data: // FALLTROUGH -tape_normal_get_data_block_1: +tape_normal_get_data_1_block: // // Read the 1st copy of the block @@ -35,19 +35,19 @@ tape_normal_get_data_block_1: // Read sync of the block ldy #$89 jsr tape_normal_sync - bcs tape_normal_get_data_fail + bcs tape_normal_get_data_1_fail jsr tape_normal_get_marker -tape_normal_get_data_loop_1: +tape_normal_get_data_1_loop: jsr tape_normal_get_byte - bcc tape_normal_get_data_loop_1_byte_OK + bcc tape_normal_get_data_1_loop_byte_OK // Problem reading a byte, try to add it to the error log tsx cpx #$20 // just to be on a safe side - bcc tape_normal_get_data_fail // branch if no more space in error log + bcc tape_normal_get_data_1_fail // branch if no more space in error log ldx PTR1 lda MEMUSS+0 @@ -60,18 +60,17 @@ tape_normal_get_data_loop_1: // Addres added to error log, check if this was a checksum jsr tape_normal_get_marker - bcc tape_normal_get_data_loop_1_advance - bcs tape_normal_get_data_block_2 + bcc tape_normal_get_data_1_loop_advance + bcs tape_normal_get_data_1_success - -tape_normal_get_data_loop_1_byte_OK: +tape_normal_get_data_1_loop_byte_OK: jsr tape_normal_get_marker bcc !+ // End of the block jsr tape_normal_update_checksum - jmp tape_normal_get_data_block_2 + jmp tape_normal_get_data_1_success !: // Store byte, calculate checksum @@ -82,7 +81,7 @@ tape_normal_get_data_loop_1_byte_OK: // FALLTROUGH -tape_normal_get_data_loop_1_advance: +tape_normal_get_data_1_loop_advance: // Advance pointer #if !HAS_OPCODES_65CE02 @@ -91,48 +90,15 @@ tape_normal_get_data_loop_1_advance: inw MEMUSS+0 #endif - jmp tape_normal_get_data_loop_1 + jmp tape_normal_get_data_1_loop -tape_normal_get_data_block_2: - - // - // Read the 2nd copy of the block - // - - // First check if there is a need to read anything - - // XXX - - // Read sync of the block - ldy #$09 - jsr tape_normal_sync - bcs tape_normal_get_data_fail - jsr tape_normal_get_marker - - // XXX implement the second pass - - - lda PTR1 - beq tape_normal_get_data_checksum - - jmp tape_normal_get_data_fail - - - - -tape_normal_get_data_checksum: - - lda RIPRTY - cmp #$01 // sets Carry if checksum verification fails - - // FALLTROUGH - -tape_normal_get_data_done: +tape_normal_get_data_1_success: + clc rts -tape_normal_get_data_fail: +tape_normal_get_data_1_fail: sec rts diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s new file mode 100644 index 00000000..32eee5a6 --- /dev/null +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -0,0 +1,51 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (normal) helper routine - data block (backup) reading +// + + +#if CONFIG_TAPE_NORMAL + + +tape_normal_get_data_2: + + // First check if there is a need to read anything + + lda PTR1 + beq tape_normal_get_data_2_checksum + + // Read sync of the block + + ldy #$09 + jsr tape_normal_sync + bcs tape_normal_get_data_2_done // Carry already set, will indicate error + jsr tape_normal_get_marker + + // FALLTROUGH + +tape_normal_get_data_2_loop: + + // XXX read missing bytes + + sec + rts + + +tape_normal_get_data_2_checksum: + + // Validate checksum + + lda RIPRTY + cmp #$01 // sets Carry if checksum verification fails + + // FALLTROUGH + +tape_normal_get_data_2_done: + + rts + + +#endif From 92c8a9d03d3c6797ced742f4c8d06887a71c0c81 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 25 Jan 2020 21:08:05 +0100 Subject: [PATCH 06/66] more work on reading second copy from tape, some cleanup --- c64/kernal/assets/cartridge_signature.s | 7 ++-- c64/kernal/assets/e8da.colour_codes.s | 8 ++-- c64/kernal/assets/fd30.vector_defaults.s | 7 ++-- c64/kernal/assets/irq_timing_hi.s | 7 ++-- c64/kernal/assets/irq_timing_lo.s | 7 ++-- c64/kernal/assets/kernal_messages.s | 7 ++-- c64/kernal/iec/save_iec.s | 2 +- c64/kernal/iostack/load_save_common.s | 2 +- c64/kernal/tape/load_tape_normal.s | 22 ++++++++--- c64/kernal/tape/tape_common.s | 4 +- c64/kernal/tape/tape_normal_get_data_2.s | 47 ++++++++++++++++++++++-- 11 files changed, 84 insertions(+), 36 deletions(-) diff --git a/c64/kernal/assets/cartridge_signature.s b/c64/kernal/assets/cartridge_signature.s index c6aabb98..a0fdcc4b 100644 --- a/c64/kernal/assets/cartridge_signature.s +++ b/c64/kernal/assets/cartridge_signature.s @@ -1,9 +1,8 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE cartridge_signature: .byte $C3,$C2,$CD,$38,$30 - - -#endif // ROM layout diff --git a/c64/kernal/assets/e8da.colour_codes.s b/c64/kernal/assets/e8da.colour_codes.s index 89849a12..003171f3 100644 --- a/c64/kernal/assets/e8da.colour_codes.s +++ b/c64/kernal/assets/e8da.colour_codes.s @@ -1,10 +1,10 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + // CHR$ codes for the 16 colours colour_codes: .byte 144,5,28,159,156,30,31,158 .byte 129,149,150,151,152,153,154,155 - - -#endif // ROM layout diff --git a/c64/kernal/assets/fd30.vector_defaults.s b/c64/kernal/assets/fd30.vector_defaults.s index 13b01e78..5e008825 100644 --- a/c64/kernal/assets/fd30.vector_defaults.s +++ b/c64/kernal/assets/fd30.vector_defaults.s @@ -1,4 +1,6 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE // // Default values for Kernal vectors - described in: @@ -25,6 +27,3 @@ vector_defaults: .word default_brk_handler // USRCMD .word LOAD // ILOAD .word SAVE // ISAVE - - -#endif // ROM layout diff --git a/c64/kernal/assets/irq_timing_hi.s b/c64/kernal/assets/irq_timing_hi.s index 794dd5cb..b884d60b 100644 --- a/c64/kernal/assets/irq_timing_hi.s +++ b/c64/kernal/assets/irq_timing_hi.s @@ -1,4 +1,6 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE // // Values for IRQ generation timer - original idea was: @@ -22,6 +24,3 @@ irq_timing_hi: // high bytes .byte >17045 // NTSC .byte >16421 // PAL - - -#endif // ROM layout diff --git a/c64/kernal/assets/irq_timing_lo.s b/c64/kernal/assets/irq_timing_lo.s index 2d18d4ec..5043d2ba 100644 --- a/c64/kernal/assets/irq_timing_lo.s +++ b/c64/kernal/assets/irq_timing_lo.s @@ -1,4 +1,6 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE // // Values for IRQ generation timer - original idea was: @@ -22,6 +24,3 @@ irq_timing_lo: // low bytes .byte <17045 // NTSC .byte <16421 // PAL - - -#endif // ROM layout \ No newline at end of file diff --git a/c64/kernal/assets/kernal_messages.s b/c64/kernal/assets/kernal_messages.s index 5f7712b1..3808770d 100644 --- a/c64/kernal/assets/kernal_messages.s +++ b/c64/kernal/assets/kernal_messages.s @@ -1,4 +1,6 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE // // Messages to be prined out by Kernal @@ -111,6 +113,3 @@ __msg_kernalfeatures: .byte $80 + $0D // end of string mark + return #endif // CONFIG_SHOW_FEATURES - - -#endif // ROM layout diff --git a/c64/kernal/iec/save_iec.s b/c64/kernal/iec/save_iec.s index a90827a7..83dff28b 100644 --- a/c64/kernal/iec/save_iec.s +++ b/c64/kernal/iec/save_iec.s @@ -74,7 +74,7 @@ save_iec: jsr iec_tx_byte #endif - jsr lvs_setup_MEMUSS + jsr lvs_STAL_to_MEMUSS ldy #$00 iec_save_loop: diff --git a/c64/kernal/iostack/load_save_common.s b/c64/kernal/iostack/load_save_common.s index 7e6e0fb2..000e88f8 100644 --- a/c64/kernal/iostack/load_save_common.s +++ b/c64/kernal/iostack/load_save_common.s @@ -80,7 +80,7 @@ lvs_handle_byte_verify: #if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO || CONFIG_IEC -lvs_setup_MEMUSS: +lvs_STAL_to_MEMUSS: lda STAL+0 sta MEMUSS+0 diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index dc5742e5..d4ad448f 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -60,15 +60,17 @@ load_tape_normal_takeover: // entry point for turbo->normal takeover load_tape_normal_header: + jsr load_MEMUSS_to_STAL + // Try to load header into tape buffer (we will restore MEMUSS later) jsr tape_normal_get_pilot_header - jsr load_tape_normal_buf_MEMUSS + jsr load_TAPE1_to_MEMUSS jsr tape_normal_get_data_1 bcs load_tape_normal_header // unable to read block, try again XXX jump to turbo detection - jsr load_tape_normal_buf_MEMUSS + jsr load_TAPE1_to_MEMUSS jsr tape_normal_get_data_2 bcs load_tape_normal_header // block load error, try again XXX jump to turbo detection @@ -90,7 +92,7 @@ load_tape_normal_header: !: // Restore MEMUSS, handle header - jsr lvs_setup_MEMUSS + jsr lvs_STAL_to_MEMUSS jsr tape_handle_header bcs load_tape_normal_header // if name does not match, look for other header @@ -108,14 +110,15 @@ load_tape_normal_payload: jsr lvs_check_EAL bne_16 tape_load_error // amount of data read does not match header info - // XXX setup MEMUSS once again + jsr lvs_STAL_to_MEMUSS jsr tape_normal_get_data_2 bcs_16 tape_load_error jmp tape_load_success -load_tape_normal_buf_MEMUSS: // set MEMUSS (start address) as tape buffer + +load_TAPE1_to_MEMUSS: // set MEMUSS (start address) as tape buffer lda TAPE1+1 sta MEMUSS+1 @@ -124,5 +127,14 @@ load_tape_normal_buf_MEMUSS: // set MEMUSS (start address) as tape buf rts +load_MEMUSS_to_STAL: // preserve MEMUSS + + lda MEMUSS+1 + sta STAL+1 + lda MEMUSS+0 + sta STAL+0 + + rts + #endif diff --git a/c64/kernal/tape/tape_common.s b/c64/kernal/tape/tape_common.s index 136d1408..8d5c6783 100644 --- a/c64/kernal/tape/tape_common.s +++ b/c64/kernal/tape/tape_common.s @@ -160,7 +160,7 @@ tape_handle_header: sbc STAL+1 sta EAL+1 - // STAL = MEMUSS XXX is it needed? + // STAL = MEMUSS lda MEMUSS+0 sta STAL+0 @@ -179,7 +179,7 @@ tape_handle_header: !: // Setup MEMUSS (see Mapping the C64, page 36) - jsr lvs_setup_MEMUSS + jsr lvs_STAL_to_MEMUSS // Print LOADING and start address diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s index 32eee5a6..ccbc56fb 100644 --- a/c64/kernal/tape/tape_normal_get_data_2.s +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -9,13 +9,20 @@ #if CONFIG_TAPE_NORMAL +tape_normal_get_data_2: + + lda RIPRTY + cmp #$01 + rts + +#elif DISABLED_DISABLED tape_normal_get_data_2: // First check if there is a need to read anything - lda PTR1 - beq tape_normal_get_data_2_checksum + // XXX lda PTR1 + // XXX beq tape_normal_get_data_2_checksum // Read sync of the block @@ -28,7 +35,32 @@ tape_normal_get_data_2: tape_normal_get_data_2_loop: - // XXX read missing bytes + // Read missing bytes + + jsr tape_normal_get_byte + bcc tape_normal_get_data_2_loop_byte_OK + + // Problem reading byte + + jsr load_cmp_log_MEMUSS + bne tape_normal_get_data_2_loop_advance + + sec + rts + +tape_normal_get_data_2_loop_byte_OK: + + jsr load_cmp_log_MEMUSS + bne tape_normal_get_data_2_loop_advance + + // This is a byte from the log + + // XXX store correct byte + + +tape_normal_get_data_2_loop_advance: + + // XXX finish the implementation sec rts @@ -48,4 +80,13 @@ tape_normal_get_data_2_done: rts + +load_cmp_log_MEMUSS: + + // XXX + +!: + rts + + #endif From 32a37e9e6fcf0f61e313ba35c06af4c9a678a7e6 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 27 Jan 2020 19:13:54 +0100 Subject: [PATCH 07/66] reading second file copy finished, but not tested yet --- c64/kernal/tape/tape_normal_get_data_2.s | 62 ++++++++++++++++++++---- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s index ccbc56fb..85f89fef 100644 --- a/c64/kernal/tape/tape_normal_get_data_2.s +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -15,7 +15,7 @@ tape_normal_get_data_2: cmp #$01 rts -#elif DISABLED_DISABLED +#elif XXX_DISABLED tape_normal_get_data_2: @@ -28,7 +28,7 @@ tape_normal_get_data_2: ldy #$09 jsr tape_normal_sync - bcs tape_normal_get_data_2_done // Carry already set, will indicate error + bcs tape_normal_get_data_2_done // Carry already set, will indicate error jsr tape_normal_get_marker // FALLTROUGH @@ -51,27 +51,50 @@ tape_normal_get_data_2_loop: tape_normal_get_data_2_loop_byte_OK: jsr load_cmp_log_MEMUSS - bne tape_normal_get_data_2_loop_advance + beq tape_normal_get_data_2_loop_byte_correct // branch if byte from the log + + jsr tape_normal_get_marker + bcs tape_normal_get_data_2_log_checksum // branch if end of blocks + bcc tape_normal_get_data_2_loop_advance + + +tape_normal_get_data_2_loop_byte_correct: // This is a byte from the log - // XXX store correct byte + jsr tape_normal_get_marker + bcs !+ + lda INBIT + ldy #$00 + sta (MEMUSS), y +!: + jsr tape_normal_update_checksum + + // FALLTROUGH tape_normal_get_data_2_loop_advance: - // XXX finish the implementation + // Advance pointer +#if !HAS_OPCODES_65CE02 + jsr lvs_advance_MEMUSS +#else + inw MEMUSS+0 +#endif - sec - rts + jmp tape_normal_get_data_2_loop -tape_normal_get_data_2_checksum: +tape_normal_get_data_2_log_checksum: + + lda PTR1 + cmp PTR2 + bne tape_normal_get_data_2_done // Carry already set // Validate checksum lda RIPRTY - cmp #$01 // sets Carry if checksum verification fails + cmp #$01 // sets Carry if checksum verification fails // FALLTROUGH @@ -83,8 +106,27 @@ tape_normal_get_data_2_done: load_cmp_log_MEMUSS: - // XXX + lda PTR1 // XXX this comparison can be probably moved somewhere else + cmp PTR2 + bne !+ + lda #$01 // to clear Zero flag + rts +!: + ldx PTR2 + lda STACK+0, x + cmp MEMUSS+0 + bne !+ + + lda STACK+1, x + cmp MEMUSS+1 + bne !+ + + // MEMUSS matches address from the log + + inc PTR2 + inc PTR2 + lda #$00 // to set Zero flag !: rts From ade6cecbb3f12b52fb55f4394963a68248a53648 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 27 Jan 2020 19:55:13 +0100 Subject: [PATCH 08/66] reading second copy works now --- CONFIG.md | 6 ++++ STATUS.md | 5 +-- c64/,,config_custom.s | 13 ++++---- c64/,,config_generic.s | 3 +- c64/,,config_mega65.s | 1 + c64/,,config_testing.s | 1 + c64/,,config_ultimate64.s | 1 + c64/kernal/tape/tape_normal_get_data_1.s | 12 ++++++- c64/kernal/tape/tape_normal_get_data_2.s | 32 +++++++++++-------- testsuite/testtape-c64-pal-normal-errors.tap | Bin 0 -> 69418 bytes 10 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 testsuite/testtape-c64-pal-normal-errors.tap diff --git a/CONFIG.md b/CONFIG.md index 409511a4..13afd09b 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -163,6 +163,12 @@ Enable this option if you are using a tape interface adapter with some audio sig Enable this option if you are using a tape interface adapter lacking tape motor control (most likely every adapter currently being sold) - this will eliminate the need to quickly press space when the program header information gets displayed. Note: if you are using a cassette player with REM port, and your adapter is connected to this port too, than you do not need this option. +### `CONFIG_TAPE_NO_ERROR_CORRECTION` + +Normal tape format contains two copies of each data block - in case some bytes from the first one are damaged, they can be corrected by reading them from the second copy. Enabling this option omits the core to read the second block. + +If using real magnetic tape - disable. Enable if only using Tapuino or other tape emulators. + ## 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. diff --git a/STATUS.md b/STATUS.md index 61d0306d..d4891fe6 100644 --- a/STATUS.md +++ b/STATUS.md @@ -12,7 +12,8 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8 * DOS wedge (direct mode only) - `@`, `@`, `@$`, `@$`, `@` * turbo tape load support (as device 7, or using `←L`), quite sophisticated: up to 250 blocks (can store bytes under I/O), automatically adjusts for tape speed differences -* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette) +* normal tape load error log is limited by free stack space only (no artificial limitation like in original ROMs) +* improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette) and emulators * extended `LOAD` command * start/end addresses are displayed, in the Final cartridge style @@ -69,7 +70,7 @@ The following ROM features are currently missing: | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | -| normal | PARTIAL | no error correction (work in progress) | +| normal | DONE | | | turbo (250 blocks) | DONE | | ## IEC bus diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index 22206333..6e5787e8 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -50,18 +50,19 @@ #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS #define CONFIG_IEC_JIFFYDOS_BLANK -// #define CONFIG_IEC_BURST_CIA1 // please keep disabled for now -// #define CONFIG_IEC_BURST_CIA2 // please keep disabled for now -// #define CONFIG_IEC_BURST_SOFT // please keep disabled for now +// #define CONFIG_IEC_BURST_CIA1 // please keep disabled for now +// #define CONFIG_IEC_BURST_CIA2 // please keep disabled for now +// #define CONFIG_IEC_BURST_SOFT // please keep disabled for now #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO -#define CONFIG_TAPE_AUTODETECT // mostly works, but not fully done yet! +#define CONFIG_TAPE_AUTODETECT // mostly works, but not fully done yet! // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL +// #define CONFIG_TAPE_NO_ERROR_CORRECTION -// #define CONFIG_RS232_UP2400 // please keep disabled for now -// #define CONFIG_RS232_UP9600 // please keep disabled for now +// #define CONFIG_RS232_UP2400 // please keep disabled for now +// #define CONFIG_RS232_UP9600 // please keep disabled for now // Multiple SID support diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index ef1c11d6..86516d96 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -48,10 +48,11 @@ #define CONFIG_IEC_JIFFYDOS #define CONFIG_IEC_JIFFYDOS_BLANK -// #define CONFIG_TAPE_NORMAL +#define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL +#define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/,,config_mega65.s b/c64/,,config_mega65.s index add9c08e..b498a38a 100644 --- a/c64/,,config_mega65.s +++ b/c64/,,config_mega65.s @@ -52,6 +52,7 @@ // #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL +#define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/,,config_testing.s b/c64/,,config_testing.s index 0f7a164f..537fcded 100644 --- a/c64/,,config_testing.s +++ b/c64/,,config_testing.s @@ -52,6 +52,7 @@ #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL +#define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index f2927c60..6293096d 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -52,6 +52,7 @@ #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL +#define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/kernal/tape/tape_normal_get_data_1.s b/c64/kernal/tape/tape_normal_get_data_1.s index 09ab2c7c..ac3353aa 100644 --- a/c64/kernal/tape/tape_normal_get_data_1.s +++ b/c64/kernal/tape/tape_normal_get_data_1.s @@ -21,8 +21,10 @@ tape_normal_get_data_1: // and pointers for error log and correction mechanism lda #$00 sta RIPRTY +#if !CONFIG_TAPE_NO_ERROR_CORRECTION sta PTR1 sta PTR2 +#endif // FALLTROUGH @@ -43,6 +45,12 @@ tape_normal_get_data_1_loop: jsr tape_normal_get_byte bcc tape_normal_get_data_1_loop_byte_OK +#if CONFIG_TAPE_NO_ERROR_CORRECTION + + bcs tape_normal_get_data_1_fail + +#else + // Problem reading a byte, try to add it to the error log tsx @@ -56,13 +64,15 @@ tape_normal_get_data_1_loop: lda MEMUSS+1 sta STACK, x inx - sta PTR1 + stx PTR1 // Addres added to error log, check if this was a checksum jsr tape_normal_get_marker bcc tape_normal_get_data_1_loop_advance bcs tape_normal_get_data_1_success +#endif + tape_normal_get_data_1_loop_byte_OK: jsr tape_normal_get_marker diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s index 85f89fef..2c378473 100644 --- a/c64/kernal/tape/tape_normal_get_data_2.s +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -9,20 +9,27 @@ #if CONFIG_TAPE_NORMAL -tape_normal_get_data_2: - +#if CONFIG_TAPE_NO_ERROR_CORRECTION + + +tape_normal_get_data_2: // XXX implement under separate name + + // Just validate the checksum + lda RIPRTY cmp #$01 rts -#elif XXX_DISABLED + +#else + tape_normal_get_data_2: // First check if there is a need to read anything - // XXX lda PTR1 - // XXX beq tape_normal_get_data_2_checksum + lda PTR1 + beq tape_normal_get_data_2_log_checksum // Read sync of the block @@ -40,25 +47,21 @@ tape_normal_get_data_2_loop: jsr tape_normal_get_byte bcc tape_normal_get_data_2_loop_byte_OK - // Problem reading byte + // Problem reading a byte - just skip it - jsr load_cmp_log_MEMUSS - bne tape_normal_get_data_2_loop_advance - - sec - rts + bcs tape_normal_get_data_2_loop_advance tape_normal_get_data_2_loop_byte_OK: jsr load_cmp_log_MEMUSS - beq tape_normal_get_data_2_loop_byte_correct // branch if byte from the log + beq tape_normal_get_data_2_loop_from_log // branch if byte from the log jsr tape_normal_get_marker bcs tape_normal_get_data_2_log_checksum // branch if end of blocks bcc tape_normal_get_data_2_loop_advance -tape_normal_get_data_2_loop_byte_correct: +tape_normal_get_data_2_loop_from_log: // This is a byte from the log @@ -132,3 +135,6 @@ load_cmp_log_MEMUSS: #endif + + +#endif diff --git a/testsuite/testtape-c64-pal-normal-errors.tap b/testsuite/testtape-c64-pal-normal-errors.tap new file mode 100644 index 0000000000000000000000000000000000000000..0e103e44e5fdd896737af171457a9298f0ae7d9d GIT binary patch literal 69418 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 VcWYH!Gc2Zz{`dd+$^SQk{|D0v`IG Date: Mon, 27 Jan 2020 20:12:30 +0100 Subject: [PATCH 09/66] cleanup in tape support code --- CONFIG.md | 6 ++--- c64/,,config_generic.s | 2 +- c64/,,config_ultimate64.s | 2 +- c64/kernal/tape/load_tape_normal.s | 10 ++++++++ c64/kernal/tape/tape_normal_get_data_2.s | 32 +++++------------------- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/CONFIG.md b/CONFIG.md index 13afd09b..73c20b49 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -147,13 +147,13 @@ Causes screen blanking during JiffyDOS file loading to increase performance. Adds a minimal normal (standard Commodore format) tape support - just LOAD command. -Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, about 900 bytes are needed, as they share some code). If unsure - enable. +Needs about 850 bytes in KERNAL segment (if both normal and turbo are enabled, about 900 bytes are needed, as they share some code). If unsure - enable. ### `CONFIG_TAPE_TURBO` Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action Replay_ and _Final_ cartridges), up to 250 blocks -Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, about 950 bytes are needed, as they share some code). If unsure - enable. +Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, about 1050 bytes are needed, as they share some code). If unsure - enable. ### `CONFIG_TAPE_NO_KEY_SENSE` @@ -167,7 +167,7 @@ Enable this option if you are using a tape interface adapter lacking tape motor Normal tape format contains two copies of each data block - in case some bytes from the first one are damaged, they can be corrected by reading them from the second copy. Enabling this option omits the core to read the second block. -If using real magnetic tape - disable. Enable if only using Tapuino or other tape emulators. +If used with `CONFIG_TAPE_NORMAL`, saves about 125 bytes in KERNAL segment. Not recommended when using real magnetic tapes. ## Multiple SID support diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index 86516d96..0390271c 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -52,7 +52,7 @@ #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL -#define CONFIG_TAPE_NO_ERROR_CORRECTION +// #define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index 6293096d..0ba624d3 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -52,7 +52,7 @@ #define CONFIG_TAPE_TURBO // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL -#define CONFIG_TAPE_NO_ERROR_CORRECTION +// #define CONFIG_TAPE_NO_ERROR_CORRECTION // Multiple SID support diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index d4ad448f..4fad6566 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -70,8 +70,13 @@ load_tape_normal_header: jsr tape_normal_get_data_1 bcs load_tape_normal_header // unable to read block, try again XXX jump to turbo detection +#if CONFIG_TAPE_NO_ERROR_CORRECTION + lda RIPRTY + cmp #$01 // sets Carry if checksum verification fails +#else jsr load_TAPE1_to_MEMUSS jsr tape_normal_get_data_2 +#endif bcs load_tape_normal_header // block load error, try again XXX jump to turbo detection // Check header type @@ -110,8 +115,13 @@ load_tape_normal_payload: jsr lvs_check_EAL bne_16 tape_load_error // amount of data read does not match header info +#if CONFIG_TAPE_NO_ERROR_CORRECTION + lda RIPRTY + cmp #$01 // sets Carry if checksum verification fails +#else jsr lvs_STAL_to_MEMUSS jsr tape_normal_get_data_2 +#endif bcs_16 tape_load_error jmp tape_load_success diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s index 2c378473..d5ec0c14 100644 --- a/c64/kernal/tape/tape_normal_get_data_2.s +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -7,21 +7,7 @@ // -#if CONFIG_TAPE_NORMAL - -#if CONFIG_TAPE_NO_ERROR_CORRECTION - - -tape_normal_get_data_2: // XXX implement under separate name - - // Just validate the checksum - - lda RIPRTY - cmp #$01 - rts - - -#else +#if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_NO_ERROR_CORRECTION tape_normal_get_data_2: @@ -42,6 +28,11 @@ tape_normal_get_data_2: tape_normal_get_data_2_loop: + // Check if there are missing bytes to read + lda PTR1 + cmp PTR2 + beq tape_normal_get_data_2_log_checksum // branch if no more errors to correct + // Read missing bytes jsr tape_normal_get_byte @@ -106,16 +97,8 @@ tape_normal_get_data_2_done: rts - load_cmp_log_MEMUSS: - lda PTR1 // XXX this comparison can be probably moved somewhere else - cmp PTR2 - bne !+ - - lda #$01 // to clear Zero flag - rts -!: ldx PTR2 lda STACK+0, x cmp MEMUSS+0 @@ -135,6 +118,3 @@ load_cmp_log_MEMUSS: #endif - - -#endif From e410bc0900a77f716ddb33b363e9f043ceae245a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 27 Jan 2020 21:08:35 +0100 Subject: [PATCH 10/66] completed tape format autodetection, updated binaries --- CONFIG.md | 10 ++++-- STATUS.md | 1 + bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes c64/,,config_custom.s | 2 +- c64/,,config_generic.s | 5 +-- c64/,,config_mega65.s | 3 +- c64/,,config_testing.s | 1 + c64/,,config_ultimate64.s | 1 + c64/kernal/tape/load_tape_normal.s | 41 +++++++++++++++++------ c64/kernal/tape/load_tape_turbo.s | 2 +- c64/kernal/tape/tape_common_autodetect.s | 3 -- c64/kernal/tape/tape_normal_get_pilot.s | 13 ++++--- 18 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CONFIG.md b/CONFIG.md index 73c20b49..a9236166 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -147,13 +147,19 @@ Causes screen blanking during JiffyDOS file loading to increase performance. Adds a minimal normal (standard Commodore format) tape support - just LOAD command. -Needs about 850 bytes in KERNAL segment (if both normal and turbo are enabled, about 900 bytes are needed, as they share some code). If unsure - enable. +Needs about 1050 bytes in KERNAL segment (if both normal and turbo are enabled, about 900 bytes are needed, as they share some code). If unsure - enable. ### `CONFIG_TAPE_TURBO` Adds a minimal turbo tape support - just LOAD command (device 7, like on _Action Replay_ and _Final_ cartridges), up to 250 blocks -Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, about 1050 bytes are needed, as they share some code). If unsure - enable. +Needs about 700 bytes in KERNAL segment (if both normal and turbo are enabled, about 1300 bytes are needed, as they share some code). If unsure - enable. + +### `CONFIG_TAPE_AUTODETECT` + +Tape format (normal/turbo) is always autodetected. + +Needs about 100 more bytes in KERNAL segment. ### `CONFIG_TAPE_NO_KEY_SENSE` diff --git a/STATUS.md b/STATUS.md index d4891fe6..d1cdaa6c 100644 --- a/STATUS.md +++ b/STATUS.md @@ -13,6 +13,7 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8 * turbo tape load support (as device 7, or using `←L`), quite sophisticated: up to 250 blocks (can store bytes under I/O), automatically adjusts for tape speed differences * normal tape load error log is limited by free stack space only (no artificial limitation like in original ROMs) +* tape format autodetection; normal vs turbo is mostly transparent to user * improved support for tape adapters (for using regular casette players and other audio devices instead of Datasette) and emulators * extended `LOAD` command diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index e3d073acbe56d49a574c70cb50146e083db16466..b8cfb3c36c64ff2b1d8ea7134e181facfb61d607 100644 GIT binary patch delta 167 zcmZp0XmFU|p}F(bN_&M%|1(x8Fg#G$@@kPHkX~wa^8W{(Me<L_rZ%7;5N%$_qRPay<<;a9Z2l}eUoj+1R%ExCY{1SoIhOqx6Hs22 nqk;uUPoB@C1ES9ISb``HUK5a{9k09)qtWCz`38{S19=4i7A#1# delta 167 zcmZp0XmFU|q3QE_rM<$X{~4)W0k_H)e4y(7b${huQv)_ zlT}$F8NDXgvo!LfshP~rD#7TrS%Y;w6Q}L_r5hA%-z#`+e!%{hnJM$*=KI|GLO@x5 TIX^~5qsejd4M0Qg%PRr^4z4kX delta 132 zcmZp0XmFU2!00_OQ5Q(`TLFnvri|X37)W0k_H)d~S`7Ab;g?>7qG zlT}$F8NDahvo!LfshP~rD#7TzS%Y;w6Q{}hr5hAX-Ya--e!%{hnJM7S=KI|GLO@x5 TIX^~5!^v^-4M0Qg%PRr^`<*c; diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index 6bbbab86d774bc6d7cdbcf32c6efb9d55fe4ec3b..d83c3f6fe35c9a2a28bb2a0829d24e7472e05626 100644 GIT binary patch delta 172 zcmZp0XmFU|p}G0hN_&M%|1(x8Fg#FL_iB+MkX~wa^8W{(Me<0Gf~K44@zoO>UO21pt#FNs#~m delta 172 zcmZp0XmFU|p{ep_rM<$X{~4)U0D28SuK)l5 diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 90a888be89e665f69f51562da95bec5f40e56eb1..ce28b37e9aabfeee71aa89aed6dda507949346f0 100644 GIT binary patch delta 4597 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 aLw+}e8$vkE@9Y&Q_W8nJM*jMBiuylU=`1(^ delta 4419 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 delta 1925 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 delta 3810 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 takeover #endif - // FALLTROUGH - -load_tape_normal_header: - jsr load_MEMUSS_to_STAL // Try to load header into tape buffer (we will restore MEMUSS later) jsr tape_normal_get_pilot_header +#if CONFIG_TAPE_AUTODETECT + bcs load_tape_normal_switch_turbo // failed, try turbo +#endif jsr load_TAPE1_to_MEMUSS jsr tape_normal_get_data_1 - bcs load_tape_normal_header // unable to read block, try again XXX jump to turbo detection +#if !CONFIG_TAPE_AUTODETECT + bcs load_tape_normal_header // unable to read block, try again +#else + bcc !+ +load_tape_normal_switch_turbo: + jsr lvs_STAL_to_MEMUSS + jmp load_tape_turbo_takeover // unable to read block, try turbo instead +!: +#endif #if CONFIG_TAPE_NO_ERROR_CORRECTION lda RIPRTY @@ -77,11 +84,15 @@ load_tape_normal_header: jsr load_TAPE1_to_MEMUSS jsr tape_normal_get_data_2 #endif - bcs load_tape_normal_header // block load error, try again XXX jump to turbo detection +#if !CONFIG_TAPE_AUTODETECT + bcs load_tape_normal_header // block load error, try again +#else + bcs load_tape_normal_switch_turbo // block load error, try turbo instead +#endif // Check header type - ldy #$00 // XXX probably can be optimized for 65C02 + ldy #$00 lda (TAPE1),y cmp #$05 @@ -90,7 +101,11 @@ load_tape_normal_header: cmp #$01 beq !+ cmp #$03 +#if !CONFIG_TAPE_AUTODETECT bne load_tape_normal_header // header types 1 and 3 are loadable, see Mapping the C64, page 77 +#else + bne load_tape_normal_takeover +#endif lda #$01 sta SA // this file is non-relocatable; override secondary address with 1 @@ -99,7 +114,11 @@ load_tape_normal_header: jsr lvs_STAL_to_MEMUSS jsr tape_handle_header +#if !CONFIG_TAPE_AUTODETECT bcs load_tape_normal_header // if name does not match, look for other header +#else + bcs load_tape_normal_takeover +#endif // FALLTROUGH diff --git a/c64/kernal/tape/load_tape_turbo.s b/c64/kernal/tape/load_tape_turbo.s index 7f8a3d9d..88feba45 100644 --- a/c64/kernal/tape/load_tape_turbo.s +++ b/c64/kernal/tape/load_tape_turbo.s @@ -37,7 +37,7 @@ load_tape_auto: #if CONFIG_TAPE_AUTODETECT -load_tape_turbo_takeover: // entry point for turbo->normal takeover +load_tape_turbo_takeover: // entry point for normal->turbo takeover jsr tape_common_autodetect bcc_16 load_tape_normal_takeover diff --git a/c64/kernal/tape/tape_common_autodetect.s b/c64/kernal/tape/tape_common_autodetect.s index 7ce2b048..88e87310 100644 --- a/c64/kernal/tape/tape_common_autodetect.s +++ b/c64/kernal/tape/tape_common_autodetect.s @@ -8,9 +8,6 @@ // Carry clear - normal, Carry set - turbo // -// XXX implement fallback to autodetection in normal - - #if CONFIG_TAPE_AUTODETECT diff --git a/c64/kernal/tape/tape_normal_get_pilot.s b/c64/kernal/tape/tape_normal_get_pilot.s index 801a2fb1..17734f33 100644 --- a/c64/kernal/tape/tape_normal_get_pilot.s +++ b/c64/kernal/tape/tape_normal_get_pilot.s @@ -16,8 +16,6 @@ #if CONFIG_TAPE_NORMAL -// XXX in tape_normal_get_pilot_header also try to detect turbo - tape_normal_get_pilot_header: // entry point, reset calibration, require 128x $40 pulses // Reading the pilot header is the first action performed, @@ -71,9 +69,14 @@ tape_normal_get_pilot_common_loop_outer: tape_normal_get_pilot_common_loop_inner: jsr tape_common_get_pulse - // XXX check for short pulses of turbo here bcc tape_normal_get_pilot_common_restart // not a pilot - try again - + +#if CONFIG_TAPE_AUTODETECT + // Try to distinguish turbo by cheecking for short signals + cmp #$B9 // see comment in tape_common_autodetect.s + bcs !+ +#endif + jsr tape_normal_calibrate_during_pilot dey @@ -82,6 +85,8 @@ tape_normal_get_pilot_common_loop_inner: dec ROPRTY bne tape_normal_get_pilot_common_loop_outer + clc +!: rts From 170a0245ca0718112d829796d687ab422e4752a8 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 27 Jan 2020 22:11:03 +0100 Subject: [PATCH 11/66] added indirect JSR for 65CE02 --- c64/aliases/,aliases_cpu.s | 8 ++++++++ ...able_kernal_1.s => 4000.mega65_vectable_kernal_1.s} | 10 ++++------ c64/kernal/init/fd50.ramtas.s | 6 +++--- c64/kernal/screen/chrout_screen_jumptable_codes.s | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) rename c64/kernal/banking/{4000.mega65_jumptable_kernal_1.s => 4000.mega65_vectable_kernal_1.s} (50%) diff --git a/c64/aliases/,aliases_cpu.s b/c64/aliases/,aliases_cpu.s index cf99d957..85f94c76 100644 --- a/c64/aliases/,aliases_cpu.s +++ b/c64/aliases/,aliases_cpu.s @@ -99,6 +99,14 @@ .byte $E3, arg } +// additional addressing modes + +.pseudocommand jsr_ind addr +{ + .var arg = addr.getValue() + .byte $22, mod(arg, $100), floor(arg / $100) +} + #endif diff --git a/c64/kernal/banking/4000.mega65_jumptable_kernal_1.s b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s similarity index 50% rename from c64/kernal/banking/4000.mega65_jumptable_kernal_1.s rename to c64/kernal/banking/4000.mega65_vectable_kernal_1.s index 001d624e..f0e86942 100644 --- a/c64/kernal/banking/4000.mega65_jumptable_kernal_1.s +++ b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// Definitions for communication with Mega65 segment KERNAL_1 +// Definitions for communication with Mega65 segment KERNAL_1 from KERNAL_0 // @@ -11,16 +11,14 @@ // Labels for jumps - - .label KERNAL_1__RAMTAS = $4000 + .label VK1__RAMTAS = $4000 #else - // Jumptable (OpenROMs private!) + // Vector table (OpenROMs private!) - - jmp RAMTAS + .word RAMTAS #endif diff --git a/c64/kernal/init/fd50.ramtas.s b/c64/kernal/init/fd50.ramtas.s index cb135a4a..3ef9461b 100644 --- a/c64/kernal/init/fd50.ramtas.s +++ b/c64/kernal/init/fd50.ramtas.s @@ -16,9 +16,9 @@ RAMTAS: #if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) - jsr map_KERNAL_1 - jsr KERNAL_1__RAMTAS - jmp map_NORMAL + jsr map_KERNAL_1 + jsr_ind VK1__RAMTAS + jmp map_NORMAL #else diff --git a/c64/kernal/screen/chrout_screen_jumptable_codes.s b/c64/kernal/screen/chrout_screen_jumptable_codes.s index 4e494b4d..499ed5ed 100644 --- a/c64/kernal/screen/chrout_screen_jumptable_codes.s +++ b/c64/kernal/screen/chrout_screen_jumptable_codes.s @@ -120,6 +120,6 @@ chrout_screen_jumptable: .word chrout_screen_DEL .word chrout_screen_RETURN -.if (mod(*, $2) == 0) { nop } // make sure routine size is always the same, needed by build system +.if (mod(*, $2) == 1) { nop } // make sure routine size is always the same, needed by build system #endif From 796b62f1666319e9b2bee38621bd867338f4ecd7 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 27 Jan 2020 22:53:30 +0100 Subject: [PATCH 12/66] dependencies fix --- Makefile | 53 +++++++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index c220d998..349c9d0a 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,8 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \ c64/kernal/tape \ c64/kernal/time - +SRC_BASIC = $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) +SRC_KERNAL = $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) # Generated files @@ -43,6 +44,11 @@ SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) GEN_BASIC = build/,generated/packed_messages.s GEN_KERNAL = +# Dependencies - helper variables + +DEP_BASIC = $(SRC_BASIC) $(SRCDIR_BASIC) $(GEN_BASIC) +DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL) + # List of tools TOOL_COLLECT_DATA = build/tools/collect_data @@ -123,46 +129,29 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies - BASIC and KERNAL build/target_custom/OUTB.BIN build/target_custom/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \ - c64/,,config_custom.s build/target_custom/KERNAL_combined.sym \ - $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_custom.s build/target_custom/KERNAL_combined.sym build/target_generic/OUTB.BIN build/target_generic/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \ - c64/,,config_generic.s build/target_generic/KERNAL_combined.sym \ - $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_generic.s build/target_generic/KERNAL_combined.sym build/target_testing/OUTB.BIN build/target_testing/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \ - c64/,,config_testing.s build/target_testing/KERNAL_combined.sym \ - $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_testing.s build/target_testing/KERNAL_combined.sym build/target_mega65/OUTB_0.BIN build/target_mega65/BASIC_0_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \ - c64/,,config_mega65.s build/target_mega65/KERNAL_0_combined.sym \ - $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_mega65.s build/target_mega65/KERNAL_0_combined.sym build/target_ultimate64/OUTB.BIN build/target_ultimate64/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_BASIC) $(SRCDIR_BASIC) \ - c64/,,config_ultimate64.s build/target_ultimate64/KERNAL_combined.sym \ - $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_ultimate64.s build/target_ultimate64/KERNAL_combined.sym build/target_custom/OUTK.BIN build/target_custom/KERNAL_combined.vs build/target_custom/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \ - c64/,,config_custom.s \ - $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_custom.s build/target_generic/OUTK.BIN build/target_generic/KERNAL_combined.vs build/target_generic/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \ - c64/,,config_generic.s \ - $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_generic.s build/target_testing/OUTK.BIN build/target_testing/KERNAL_combined.vs build/target_testing/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \ - c64/,,config_testing.s \ - $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_testing.s build/target_mega65/OUTK_0.BIN build/target_mega65/KERNAL_0_combined.vs build/target_mega65/KERNAL_0_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \ - c64/,,config_mega65.s \ - $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_mega65.s build/target_ultimate64/OUTK.BIN build/target_ultimate64/KERNAL_combined.vs build/target_ultimate64/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(GEN_KERNAL) $(SRCDIR_KERNAL) \ - c64/,,config_ultimate64.s \ - $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_ultimate64.s + +build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_mega65.s build/target_custom/newrom: build/target_custom/OUTB.BIN build/target_custom/OUTK.BIN build/target_generic/newrom: build/target_generic/OUTB.BIN build/target_generic/OUTK.BIN @@ -216,7 +205,7 @@ build/target_mega65/OUTK_0.BIN build/target_mega65/KERNAL_0_combined.vs build/ta @rm -f $@* build/target_mega65/KERNAL_0* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d build/target_mega65 -l e4d3 -h ffff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL) -build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: $(TOOL_BUILD_SEGMENT) +build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: @mkdir -p build/target_mega65 @rm -f $@* build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d build/target_mega65 -l 4000 -h 5fff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL) From d489e7bf416f3b59ce434c3eb4290834f57bbbcc Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 17:35:42 +0100 Subject: [PATCH 13/66] tape routines can now be placed in Mega65 extra ROM space commit 2f27e29758da1f1ec965588c0712125051a6f71a Merge: ba722b1 796b62f Author: FeralChild64 Date: Tue Jan 28 17:34:53 2020 +0100 Merge branch 'master' into tape_redirect commit ba722b17e627af7dd067932688de0a3d86423e37 Author: FeralChild64 Date: Tue Jan 28 17:28:19 2020 +0100 finished Mega65 variant of tape routines commit 47de685f2e08576504c5e00a5b7cb78498d22e72 Author: FeralChild64 Date: Mon Jan 27 23:06:45 2020 +0100 compilation fix commit c3641acec049a7a6b53c35795b1f9e2df212cec2 Author: FeralChild64 Date: Mon Jan 27 22:53:30 2020 +0100 dependencies fix commit dfad7a30bde043fa077005624dde1de4b72573b6 Merge: e4b0ec9 e410bc0 Author: FeralChild64 Date: Mon Jan 27 21:25:49 2020 +0100 Merge branch 'master' into tape_redirect commit e4b0ec9c85861bde2ce52e0828d3bf895a681e17 Author: FeralChild64 Date: Sat Jan 25 22:25:20 2020 +0100 initial attempt to move tape code to Mega65 extra ROM --- c64/,,config_custom.s | 2 +- c64/,,config_generic.s | 2 +- c64/,,config_mega65.s | 6 +- c64/,,config_ultimate64.s | 2 +- c64/aliases/,aliases_ram_lowmem.s | 20 ++++--- c64/basic/init/e394.basic_cold_start.s | 4 ++ .../banking/4000.mega65_vectable_kernal_1.s | 26 +++++++- c64/kernal/banking/mega65_imports.s | 55 +++++++++++++++++ c64/kernal/banking/mega65_proxies.s | 59 +++++++++++++++++++ .../banking/mega65_redirect_load_tape.s | 39 ++++++++++++ c64/kernal/memory/membot.s | 7 +-- c64/kernal/tape/load_tape_normal.s | 2 +- c64/kernal/tape/load_tape_turbo.s | 6 +- c64/kernal/tape/tape_common.s | 2 +- c64/kernal/tape/tape_common_autodetect.s | 2 +- c64/kernal/tape/tape_common_clean_sid.s | 2 +- c64/kernal/tape/tape_common_ditch_verify.s | 2 +- c64/kernal/tape/tape_common_get_pulse.s | 2 +- c64/kernal/tape/tape_common_prepare_cia.s | 2 +- c64/kernal/tape/tape_common_screen.s | 2 +- .../tape/tape_normal_byte_store_mega65.s | 19 ++++++ c64/kernal/tape/tape_normal_calibrate.s | 2 +- c64/kernal/tape/tape_normal_get_bit.s | 2 +- c64/kernal/tape/tape_normal_get_byte.s | 2 +- c64/kernal/tape/tape_normal_get_data_1.s | 6 +- c64/kernal/tape/tape_normal_get_data_2.s | 6 +- c64/kernal/tape/tape_normal_get_marker.s | 2 +- c64/kernal/tape/tape_normal_get_pilot.s | 2 +- c64/kernal/tape/tape_normal_sync.s | 2 +- c64/kernal/tape/tape_normal_update_checksum.s | 2 +- .../tape/tape_turbo_byte_store_mega65.s | 19 ++++++ c64/kernal/tape/tape_turbo_bytestore.s | 3 +- c64/kernal/tape/tape_turbo_get_bit.s | 2 +- c64/kernal/tape/tape_turbo_get_byte.s | 2 +- c64/kernal/tape/tape_turbo_sync.s | 2 +- c64/kernal/tape/tape_turbo_sync_first.s | 2 +- 36 files changed, 275 insertions(+), 44 deletions(-) create mode 100644 c64/kernal/banking/mega65_imports.s create mode 100644 c64/kernal/banking/mega65_proxies.s create mode 100644 c64/kernal/banking/mega65_redirect_load_tape.s create mode 100644 c64/kernal/tape/tape_normal_byte_store_mega65.s create mode 100644 c64/kernal/tape/tape_turbo_byte_store_mega65.s diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index bf190455..d5983fcb 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -116,7 +116,7 @@ // Screen editor #define CONFIG_EDIT_STOPQUOTE -#define CONFIG_EDIT_TABULATORS +// #define CONFIG_EDIT_TABULATORS // Software features diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index 4bdb6ab0..b74339af 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -107,7 +107,7 @@ // Screen editor #define CONFIG_EDIT_STOPQUOTE -#define CONFIG_EDIT_TABULATORS +// #define CONFIG_EDIT_TABULATORS // Software features diff --git a/c64/,,config_mega65.s b/c64/,,config_mega65.s index 90b88161..6bd9ee5c 100644 --- a/c64/,,config_mega65.s +++ b/c64/,,config_mega65.s @@ -48,9 +48,9 @@ #define CONFIG_IEC_JIFFYDOS #define CONFIG_IEC_JIFFYDOS_BLANK -// #define CONFIG_TAPE_NORMAL -// #define CONFIG_TAPE_TURBO -// #define CONFIG_TAPE_AUTODETECT +#define CONFIG_TAPE_NORMAL +#define CONFIG_TAPE_TURBO +#define CONFIG_TAPE_AUTODETECT // #define CONFIG_TAPE_NO_KEY_SENSE // #define CONFIG_TAPE_NO_MOTOR_CONTROL // #define CONFIG_TAPE_NO_ERROR_CORRECTION diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index 62e4d18b..9cbd6819 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -107,7 +107,7 @@ // Screen editor #define CONFIG_EDIT_STOPQUOTE -#define CONFIG_EDIT_TABULATORS +// #define CONFIG_EDIT_TABULATORS // Software features diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 41aed18a..efb85ef8 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -291,18 +291,24 @@ // -// Definitions foor tape functionality +// Definitions for tape functionality // #if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO - .label __normal_time_S = IRQTMP+0 // duration of the short pulse - .label __normal_time_M = IRQTMP+1 // duration of the medium pulse + .label __normal_time_S = IRQTMP+0 // duration of the short pulse + .label __normal_time_M = IRQTMP+1 // duration of the medium pulse - .label __turbo_half_S = IRQTMP+0 // half-duration of the short pulse - .label __turbo_half_L = IRQTMP+1 // half-duration of the long pulse + .label __turbo_half_S = IRQTMP+0 // half-duration of the short pulse + .label __turbo_half_L = IRQTMP+1 // half-duration of the long pulse - .label __pulse_threshold = SVXT // pulse classification threshold - .label __pulse_threshold_ML = SYNO // M/L pulse classification threshold, for normal only + .label __pulse_threshold = SVXT // pulse classification threshold + .label __pulse_threshold_ML = SYNO // M/L pulse classification threshold, for normal only + +#endif + +#if CONFIG_TAPE_TURBO + + .label __tape_turbo_bytestore = STACK // location of byte storage helper routine #endif diff --git a/c64/basic/init/e394.basic_cold_start.s b/c64/basic/init/e394.basic_cold_start.s index 76419f1c..c1ada5f1 100644 --- a/c64/basic/init/e394.basic_cold_start.s +++ b/c64/basic/init/e394.basic_cold_start.s @@ -8,6 +8,8 @@ basic_cold_start: +// #if !ROM_LAYOUT_M65 + // Before doing anything, check if we have a compatible BASIC/KERNAL pair ldy #(__rom_revision_basic_end - rom_revision_basic - 1) @@ -22,6 +24,8 @@ basic_cold_start: dey bpl !-- +// #endif + // Remaining part would not fit here jmp basic_cold_start_internal diff --git a/c64/kernal/banking/4000.mega65_vectable_kernal_1.s b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s index f0e86942..775c1f93 100644 --- a/c64/kernal/banking/4000.mega65_vectable_kernal_1.s +++ b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s @@ -9,10 +9,12 @@ #if SEGMENT_KERNAL_0 - // Labels for jumps - - .label VK1__RAMTAS = $4000 + // Label definitions + .label VK1__RAMTAS = $4000 + 2 * 0 + .label VK1__load_tape_normal = $4000 + 2 * 1 + .label VK1__load_tape_turbo = $4000 + 2 * 2 + .label VK1__load_tape_auto = $4000 + 2 * 3 #else @@ -20,5 +22,23 @@ .word RAMTAS +#if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_AUTODETECT + .word load_tape_normal +#else + .word $0000 +#endif + +#if CONFIG_TAPE_TURBO && !CONFIG_TAPE_AUTODETECT + .word load_tape_turbo +#else + .word $0000 +#endif + +#if CONFIG_TAPE_AUTODETECT + .word load_tape_auto +#else + .word $0000 +#endif + #endif diff --git a/c64/kernal/banking/mega65_imports.s b/c64/kernal/banking/mega65_imports.s new file mode 100644 index 00000000..3cc727e6 --- /dev/null +++ b/c64/kernal/banking/mega65_imports.s @@ -0,0 +1,55 @@ +// #LAYOUT# M65 KERNAL_1 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Definitions for calling Mega65 segment KERNAL_0 routines from KERNAL_1 +// + +#import "KERNAL_0_combined.sym" + + +.label STOP = KERNAL_0.STOP +.label udtim_keyboard = KERNAL_0.udtim_keyboard + +.label wait_x_bars = KERNAL_0.wait_x_bars + + +#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO + +.label screen_on = KERNAL_0.screen_on +.label screen_off = KERNAL_0.screen_off +.label tape_motor_on = KERNAL_0.tape_motor_on +.label tape_motor_off = KERNAL_0.tape_motor_off + +.label lvs_display_loading_verifying = KERNAL_0.proxy_K1_lvs_display_loading_verifying +.label lvs_display_done = KERNAL_0.proxy_K1_lvs_display_done +.label lvs_return_last_address = KERNAL_0.proxy_K1_lvs_return_last_address +.label lvs_device_not_found_error = KERNAL_0.proxy_K1_lvs_device_not_found_error +.label lvs_load_verify_error = KERNAL_0.proxy_K1_lvs_load_verify_error + +.label lvs_check_EAL = KERNAL_0.lvs_check_EAL +.label lvs_STAL_to_MEMUSS = KERNAL_0.lvs_STAL_to_MEMUSS + +.label kernalerror_ROUTINE_TERMINATED = KERNAL_0.proxy_K1_kernalerror_ROUTINE_TERMINATED + +.label print_kernal_message = KERNAL_0.proxy_K1_print_kernal_message +.label print_return = KERNAL_0.proxy_K1_print_return + +.label __MSG_KERNAL_PRESS_PLAY = KERNAL_0.__MSG_KERNAL_PRESS_PLAY +.label __MSG_KERNAL_FOUND = KERNAL_0.__MSG_KERNAL_FOUND + +#endif + + +#if CONFIG_TAPE_NORMAL + +.label tape_normal_byte_store = KERNAL_0.tape_normal_byte_store + +#endif + + +#if CONFIG_TAPE_TURBO + +.label tape_turbo_byte_store = KERNAL_0.tape_turbo_byte_store + +#endif diff --git a/c64/kernal/banking/mega65_proxies.s b/c64/kernal/banking/mega65_proxies.s new file mode 100644 index 00000000..94026367 --- /dev/null +++ b/c64/kernal/banking/mega65_proxies.s @@ -0,0 +1,59 @@ +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Proxies for calling Mega65 segment KERNAL_0 routines from KERNAL_1 +// + + +#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO + + +proxy_K1_kernalerror_ROUTINE_TERMINATED: + + jsr map_NORMAL + jmp kernalerror_ROUTINE_TERMINATED + + +proxy_K1_lvs_display_loading_verifying: + + jsr map_NORMAL + jsr lvs_display_loading_verifying + jmp map_KERNAL_1 + +proxy_K1_lvs_display_done: + + jsr map_NORMAL + jsr lvs_display_done + jmp map_KERNAL_1 + +proxy_K1_lvs_return_last_address: + + jsr map_NORMAL + jmp lvs_return_last_address + +proxy_K1_lvs_device_not_found_error: + + jsr map_NORMAL + jmp lvs_device_not_found_error + +proxy_K1_lvs_load_verify_error: + + jsr map_NORMAL + jmp lvs_load_verify_error + + +proxy_K1_print_kernal_message: + + jsr map_NORMAL + jsr print_kernal_message + jmp map_KERNAL_1 + +proxy_K1_print_return: + + jsr map_NORMAL + jsr print_return + jmp map_KERNAL_1 + + +#endif diff --git a/c64/kernal/banking/mega65_redirect_load_tape.s b/c64/kernal/banking/mega65_redirect_load_tape.s new file mode 100644 index 00000000..56061aca --- /dev/null +++ b/c64/kernal/banking/mega65_redirect_load_tape.s @@ -0,0 +1,39 @@ +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// ROM routine call redirect for tape loading +// + + +#if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_AUTODETECT + +load_tape_normal: + + jsr map_KERNAL_1 + jsr_ind VK1__load_tape_normal + jmp map_NORMAL + +#endif + + +#if CONFIG_TAPE_TURBO && !CONFIG_TAPE_AUTODETECT + +load_tape_turbo: + + jsr map_KERNAL_1 + jsr_ind VK1__load_tape_turbo + jmp map_NORMAL + +#endif + + +#if CONFIG_TAPE_AUTODETECT + +load_tape_auto: + + jsr map_KERNAL_1 + jsr_ind VK1__load_tape_auto + jmp map_NORMAL + +#endif diff --git a/c64/kernal/memory/membot.s b/c64/kernal/memory/membot.s index 0da97fdc..0a9987ea 100644 --- a/c64/kernal/memory/membot.s +++ b/c64/kernal/memory/membot.s @@ -1,4 +1,6 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE // // Official Kernal routine, described in: @@ -24,6 +26,3 @@ membot_set: stx MEMSTR+0 rts - - -#endif // ROM layout diff --git a/c64/kernal/tape/load_tape_normal.s b/c64/kernal/tape/load_tape_normal.s index e9f9c733..c53dabdb 100644 --- a/c64/kernal/tape/load_tape_normal.s +++ b/c64/kernal/tape/load_tape_normal.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/load_tape_turbo.s b/c64/kernal/tape/load_tape_turbo.s index 88feba45..ab42535d 100644 --- a/c64/kernal/tape/load_tape_turbo.s +++ b/c64/kernal/tape/load_tape_turbo.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // @@ -128,7 +128,11 @@ load_tape_turbo_payload: load_tape_turbo_loop: jsr tape_turbo_get_byte +#if ROM_LAYOUT_M65 + jsr tape_turbo_byte_store +#else jsr __tape_turbo_bytestore // like 'sta (MEMUSS),y' - but under I/O +#endif eor PRTY // handle checksum sta PRTY diff --git a/c64/kernal/tape/tape_common.s b/c64/kernal/tape/tape_common.s index 8d5c6783..94d125b0 100644 --- a/c64/kernal/tape/tape_common.s +++ b/c64/kernal/tape/tape_common.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_autodetect.s b/c64/kernal/tape/tape_common_autodetect.s index 88e87310..5ea9aebe 100644 --- a/c64/kernal/tape/tape_common_autodetect.s +++ b/c64/kernal/tape/tape_common_autodetect.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_clean_sid.s b/c64/kernal/tape/tape_common_clean_sid.s index 80b4bbee..a320faef 100644 --- a/c64/kernal/tape/tape_common_clean_sid.s +++ b/c64/kernal/tape/tape_common_clean_sid.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_ditch_verify.s b/c64/kernal/tape/tape_common_ditch_verify.s index 3fa1fcbb..b7d21d8a 100644 --- a/c64/kernal/tape/tape_common_ditch_verify.s +++ b/c64/kernal/tape/tape_common_ditch_verify.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_get_pulse.s b/c64/kernal/tape/tape_common_get_pulse.s index dfbba663..b194ccd7 100644 --- a/c64/kernal/tape/tape_common_get_pulse.s +++ b/c64/kernal/tape/tape_common_get_pulse.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_prepare_cia.s b/c64/kernal/tape/tape_common_prepare_cia.s index ce172a03..d4d6302c 100644 --- a/c64/kernal/tape/tape_common_prepare_cia.s +++ b/c64/kernal/tape/tape_common_prepare_cia.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_common_screen.s b/c64/kernal/tape/tape_common_screen.s index fe2742ac..aaf7a150 100644 --- a/c64/kernal/tape/tape_common_screen.s +++ b/c64/kernal/tape/tape_common_screen.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_byte_store_mega65.s b/c64/kernal/tape/tape_normal_byte_store_mega65.s new file mode 100644 index 00000000..4c8cc13f --- /dev/null +++ b/c64/kernal/tape/tape_normal_byte_store_mega65.s @@ -0,0 +1,19 @@ +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (normal) helper routine - byte storage when ban changing is needed +// + + +#if CONFIG_TAPE_NORMAL + + +tape_normal_byte_store: + + jsr map_NORMAL + sta (MEMUSS), y + jmp map_KERNAL_1 + + +#endif diff --git a/c64/kernal/tape/tape_normal_calibrate.s b/c64/kernal/tape/tape_normal_calibrate.s index 5a517018..71201c5c 100644 --- a/c64/kernal/tape/tape_normal_calibrate.s +++ b/c64/kernal/tape/tape_normal_calibrate.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_get_bit.s b/c64/kernal/tape/tape_normal_get_bit.s index 960f92ee..96ab54d4 100644 --- a/c64/kernal/tape/tape_normal_get_bit.s +++ b/c64/kernal/tape/tape_normal_get_bit.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_get_byte.s b/c64/kernal/tape/tape_normal_get_byte.s index 98c98ee1..35e18bec 100644 --- a/c64/kernal/tape/tape_normal_get_byte.s +++ b/c64/kernal/tape/tape_normal_get_byte.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_get_data_1.s b/c64/kernal/tape/tape_normal_get_data_1.s index ac3353aa..8b07ccb7 100644 --- a/c64/kernal/tape/tape_normal_get_data_1.s +++ b/c64/kernal/tape/tape_normal_get_data_1.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // @@ -86,7 +86,11 @@ tape_normal_get_data_1_loop_byte_OK: // Store byte, calculate checksum lda INBIT ldy #$00 +#if ROM_LAYOUT_M65 + jsr tape_normal_byte_store +#else sta (MEMUSS), y +#endif jsr tape_normal_update_checksum // FALLTROUGH diff --git a/c64/kernal/tape/tape_normal_get_data_2.s b/c64/kernal/tape/tape_normal_get_data_2.s index d5ec0c14..cf2a3763 100644 --- a/c64/kernal/tape/tape_normal_get_data_2.s +++ b/c64/kernal/tape/tape_normal_get_data_2.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // @@ -61,7 +61,11 @@ tape_normal_get_data_2_loop_from_log: lda INBIT ldy #$00 +#if ROM_LAYOUT_M65 + jsr tape_normal_byte_store +#else sta (MEMUSS), y +#endif !: jsr tape_normal_update_checksum diff --git a/c64/kernal/tape/tape_normal_get_marker.s b/c64/kernal/tape/tape_normal_get_marker.s index bab658f7..2055c581 100644 --- a/c64/kernal/tape/tape_normal_get_marker.s +++ b/c64/kernal/tape/tape_normal_get_marker.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_get_pilot.s b/c64/kernal/tape/tape_normal_get_pilot.s index 17734f33..214a7e1f 100644 --- a/c64/kernal/tape/tape_normal_get_pilot.s +++ b/c64/kernal/tape/tape_normal_get_pilot.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_sync.s b/c64/kernal/tape/tape_normal_sync.s index 5fbd5779..e7ba9eb9 100644 --- a/c64/kernal/tape/tape_normal_sync.s +++ b/c64/kernal/tape/tape_normal_sync.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_normal_update_checksum.s b/c64/kernal/tape/tape_normal_update_checksum.s index d808f872..8b60d534 100644 --- a/c64/kernal/tape/tape_normal_update_checksum.s +++ b/c64/kernal/tape/tape_normal_update_checksum.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_turbo_byte_store_mega65.s b/c64/kernal/tape/tape_turbo_byte_store_mega65.s new file mode 100644 index 00000000..bfc4b77c --- /dev/null +++ b/c64/kernal/tape/tape_turbo_byte_store_mega65.s @@ -0,0 +1,19 @@ +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Tape (turbo) helper routine - byte storage when ban changing is needed +// + + +#if CONFIG_TAPE_TURBO + + +tape_turbo_byte_store: + + jsr map_NORMAL + jsr __tape_turbo_bytestore // like 'sta (MEMUSS),y' - but under I/O + jmp map_KERNAL_1 + + +#endif diff --git a/c64/kernal/tape/tape_turbo_bytestore.s b/c64/kernal/tape/tape_turbo_bytestore.s index aa70358c..25bf7a6b 100644 --- a/c64/kernal/tape/tape_turbo_bytestore.s +++ b/c64/kernal/tape/tape_turbo_bytestore.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // @@ -16,7 +16,6 @@ #if CONFIG_TAPE_TURBO -.label __tape_turbo_bytestore = STACK .label __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 7 .label __tape_turbo_bytestore_size = __tape_turbo_bytestore_source_end - tape_turbo_bytestore_source diff --git a/c64/kernal/tape/tape_turbo_get_bit.s b/c64/kernal/tape/tape_turbo_get_bit.s index eaf5be4e..a903a4d5 100644 --- a/c64/kernal/tape/tape_turbo_get_bit.s +++ b/c64/kernal/tape/tape_turbo_get_bit.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_turbo_get_byte.s b/c64/kernal/tape/tape_turbo_get_byte.s index 01f76f40..6d4753b2 100644 --- a/c64/kernal/tape/tape_turbo_get_byte.s +++ b/c64/kernal/tape/tape_turbo_get_byte.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_turbo_sync.s b/c64/kernal/tape/tape_turbo_sync.s index a20c94da..81106fb0 100644 --- a/c64/kernal/tape/tape_turbo_sync.s +++ b/c64/kernal/tape/tape_turbo_sync.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/tape/tape_turbo_sync_first.s b/c64/kernal/tape/tape_turbo_sync_first.s index caa4bff2..4e200bb9 100644 --- a/c64/kernal/tape/tape_turbo_sync_first.s +++ b/c64/kernal/tape/tape_turbo_sync_first.s @@ -1,5 +1,5 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE // #LAYOUT# * * #IGNORE // From c41316d482b7aeab4c544572a9c531a560da1940 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 17:44:45 +0100 Subject: [PATCH 14/66] updated documentation, makefile, and binaries --- CONFIG.md | 6 +- Makefile | 150 +++++++++++++++++++++----------------- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes doc/Development.md | 10 +-- 10 files changed, 93 insertions(+), 73 deletions(-) diff --git a/CONFIG.md b/CONFIG.md index a9236166..fd47a97c 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -113,7 +113,7 @@ Uses RAM under BASIC, I/O and KERNAL, takes over `$C000`-`$CFFF` area requires s Comparing to standard memory model, it needs about 180 bytes in BASIC segment and 80 bytes in KERNAL segment - at the moment of doing the test, these values are expected to change often. -## I/O devices +## IEC devices ### `CONFIG_IEC` @@ -143,6 +143,10 @@ Needs about 430 bytes in KERNAL segment. If unsure - enable. Causes screen blanking during JiffyDOS file loading to increase performance. +## Tape support + +Note: for Mega65 most of the tape support code is placed in it's extended ROM; very little of the (tiny) KERNAL segment is used. + ### `CONFIG_TAPE_NORMAL` Adds a minimal normal (standard Commodore format) tape support - just LOAD command. diff --git a/Makefile b/Makefile index 349c9d0a..439cf4d0 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,22 @@ SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) GEN_BASIC = build/,generated/packed_messages.s GEN_KERNAL = +# List of build directories + +DIR_CUSTOM = build/target_custom +DIR_GENERIC = build/target_generic +DIR_TESTING = build/target_testing +DIR_MEGA65 = build/target_mega65 +DIR_ULTIMATE64 = build/target_ultimate64 + +# List of config files + +CFG_CUSTOM = c64/,,config_custom.s +CFG_GENERIC = c64/,,config_generic.s +CFG_TESTING = c64/,,config_testing.s +CFG_MEGA65 = c64/,,config_mega65.s +CFG_ULTIMATE64 = c64/,,config_ultimate64.s + # Dependencies - helper variables DEP_BASIC = $(SRC_BASIC) $(SRCDIR_BASIC) $(GEN_BASIC) @@ -128,54 +144,54 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies - BASIC and KERNAL -build/target_custom/OUTB.BIN build/target_custom/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_custom.s build/target_custom/KERNAL_combined.sym -build/target_generic/OUTB.BIN build/target_generic/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_generic.s build/target_generic/KERNAL_combined.sym -build/target_testing/OUTB.BIN build/target_testing/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_testing.s build/target_testing/KERNAL_combined.sym -build/target_mega65/OUTB_0.BIN build/target_mega65/BASIC_0_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_mega65.s build/target_mega65/KERNAL_0_combined.sym -build/target_ultimate64/OUTB.BIN build/target_ultimate64/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) c64/,,config_ultimate64.s build/target_ultimate64/KERNAL_combined.sym +$(DIR_CUSTOM)/OUTB.BIN $(DIR_CUSTOM)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_CUSTOM) $(DIR_CUSTOM)/KERNAL_combined.sym +$(DIR_GENERIC)/OUTB.BIN $(DIR_GENERIC)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_GENERIC) $(DIR_GENERIC)/KERNAL_combined.sym +$(DIR_TESTING)/OUTB.BIN $(DIR_TESTING)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_TESTING) $(DIR_TESTING)/KERNAL_combined.sym +$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym +$(DIR_ULTIMATE64)/OUTB.BIN $(DIR_ULTIMATE64)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_ULTIMATE64) $(DIR_ULTIMATE64)/KERNAL_combined.sym -build/target_custom/OUTK.BIN build/target_custom/KERNAL_combined.vs build/target_custom/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_custom.s -build/target_generic/OUTK.BIN build/target_generic/KERNAL_combined.vs build/target_generic/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_generic.s -build/target_testing/OUTK.BIN build/target_testing/KERNAL_combined.vs build/target_testing/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_testing.s -build/target_mega65/OUTK_0.BIN build/target_mega65/KERNAL_0_combined.vs build/target_mega65/KERNAL_0_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_mega65.s -build/target_ultimate64/OUTK.BIN build/target_ultimate64/KERNAL_combined.vs build/target_ultimate64/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_ultimate64.s +$(DIR_CUSTOM)/OUTK.BIN $(DIR_CUSTOM)/KERNAL_combined.vs $(DIR_CUSTOM)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_CUSTOM) +$(DIR_GENERIC)/OUTK.BIN $(DIR_GENERIC)/KERNAL_combined.vs $(DIR_GENERIC)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_GENERIC) +$(DIR_TESTING)/OUTK.BIN $(DIR_TESTING)KERNAL_combined.vs $(DIR_TESTING)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_TESTING) +$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) +$(DIR_ULTIMATE64)/OUTK.BIN $(DIR_ULTIMATE64)/KERNAL_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_ULTIMATE64) -build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) c64/,,config_mega65.s +$(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym -build/target_custom/newrom: build/target_custom/OUTB.BIN build/target_custom/OUTK.BIN -build/target_generic/newrom: build/target_generic/OUTB.BIN build/target_generic/OUTK.BIN -build/target_testing/newrom: build/target_testing/OUTB.BIN build/target_testing/OUTK.BIN -build/target_mega65/newrom_0: build/target_mega65/OUTB_0.BIN build/target_mega65/OUTK_0.BIN -build/target_ultimate64/newrom: build/target_ultimate64/OUTB.BIN build/target_ultimate64/OUTK.BIN +$(DIR_CUSTOM)/newrom: $(DIR_CUSTOM)/OUTB.BIN $(DIR_CUSTOM)/OUTK.BIN +$(DIR_GENERIC)/newrom: $(DIR_GENERIC)/OUTB.BIN $(DIR_GENERIC)/OUTK.BIN +$(DIR_TESTING)/newrom: $(DIR_TESTING)/OUTB.BIN $(DIR_TESTING)/OUTK.BIN +$(DIR_MEGA65)/newrom_0: $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN +$(DIR_ULTIMATE64)/newrom: $(DIR_ULTIMATE64)/OUTB.BIN $(DIR_ULTIMATE64)/OUTK.BIN -build/kernal_custom.rom: build/target_custom/newrom -build/kernal_generic.rom: build/target_generic/newrom -build/kernal_testing.rom: build/target_testing/newrom -build/kernal_mega65.rom_0: build/target_mega65/newrom_0 -build/kernal_ultimate64.rom: build/target_ultimate64/newrom +build/kernal_custom.rom: $(DIR_CUSTOM)/newrom +build/kernal_generic.rom: $(DIR_GENERIC)/newrom +build/kernal_testing.rom: $(DIR_TESTING)/newrom +build/kernal_mega65.rom_0: $(DIR_MEGA65)/newrom_0 +build/kernal_ultimate64.rom: $(DIR_ULTIMATE64)/newrom -build/basic_custom.rom: build/target_custom/newrom -build/basic_generic.rom: build/target_generic/newrom -build/basic_testing.rom: build/target_testing/newrom -build/basic_mega65.rom_0: build/target_mega65/newrom_0 -build/basic_ultimate64.rom: build/target_ultimate64/newrom +build/basic_custom.rom: $(DIR_CUSTOM)/newrom +build/basic_generic.rom: $(DIR_GENERIC)/newrom +build/basic_testing.rom: $(DIR_TESTING)/newrom +build/basic_mega65.rom_0: $(DIR_MEGA65)/newrom_0 +build/basic_ultimate64.rom: $(DIR_ULTIMATE64)/newrom -build/symbols_custom.vs: build/target_custom/BASIC_combined.vs build/target_custom/KERNAL_combined.vs -build/symbols_generic.vs: build/target_generic/BASIC_combined.vs build/target_generic/KERNAL_combined.vs -build/symbols_testing.vs: build/target_testing/BASIC_combined.vs build/target_testing/KERNAL_combined.vs -build/symbols_mega65_0.vs: build/target_mega65/BASIC_0_combined.vs build/target_mega65/KERNAL_0_combined.vs -build/symbols_ultimate64.vs: build/target_ultimate64/BASIC_combined.vs build/target_ultimate64/KERNAL_combined.vs +build/symbols_custom.vs: $(DIR_CUSTOM)/BASIC_combined.vs $(DIR_CUSTOM)/KERNAL_combined.vs +build/symbols_generic.vs: $(DIR_GENERIC)/BASIC_combined.vs $(DIR_GENERIC)/KERNAL_combined.vs +build/symbols_testing.vs: $(DIR_TESTING)/BASIC_combined.vs $(DIR_TESTING)/KERNAL_combined.vs +build/symbols_mega65_0.vs: $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.vs +build/symbols_ultimate64.vs: $(DIR_ULTIMATE64)/BASIC_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.vs # Rules - BASIC and KERNAL @@ -195,20 +211,20 @@ build/target_%/OUTK.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_ @rm -f $@* build/target_$*/KERNAL* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s KERNAL -i KERNAL-$* -o OUTK.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL) -build/target_mega65/OUTB_0.BIN build/target_mega65/BASIC_0_combined.vs: - @mkdir -p build/target_mega65 - @rm -f $@* build/target_mega65/BASIC_0* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d build/target_mega65 -l a000 -h e4d2 c64/,,config_mega65.s $(SRCDIR_BASIC) $(GEN_BASIC) +$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs: + @mkdir -p $(DIR_MEGA65) + @rm -f $@* $(DIR_MEGA65)/BASIC_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d $(DIR_MEGA65) -l a000 -h e4d2 $(CFG_MEGA65) $(SRCDIR_BASIC) $(GEN_BASIC) -build/target_mega65/OUTK_0.BIN build/target_mega65/KERNAL_0_combined.vs build/target_mega65/KERNAL_0_combined.sym: - @mkdir -p build/target_mega65 - @rm -f $@* build/target_mega65/KERNAL_0* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d build/target_mega65 -l e4d3 -h ffff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL) +$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: + @mkdir -p $(DIR_MEGA65) + @rm -f $@* $(DIR_MEGA65)/KERNAL_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d $(DIR_MEGA65) -l e4d3 -h ffff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) -build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: - @mkdir -p build/target_mega65 - @rm -f $@* build/target_mega65/kernal.seg_1 build/target_mega65/KERNAL_1* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d build/target_mega65 -l 4000 -h 5fff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL) +$(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: + @mkdir -p $(DIR_MEGA65) + @rm -f $@* $(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d $(DIR_MEGA65) -l 4000 -h 5fff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) .PRECIOUS: build/target_%/newrom build/target_%/newrom: @@ -226,35 +242,35 @@ build/basic_%.rom: build/symbols_%.vs: sort build/target_$*/BASIC_combined.vs build/target_$*/KERNAL_combined.vs | uniq | grep -v "__" > $@ -build/target_mega65/newrom_0: - cat build/target_mega65/OUTB_0.BIN build/target_mega65/OUTK_0.BIN > $@ +$(DIR_MEGA65)/newrom_0: + cat $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN > $@ build/kernal_mega65.rom_0: - dd if=build/target_mega65/newrom_0 bs=8192 count=1 skip=2 of=$@ + dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=2 of=$@ build/basic_mega65.rom_0: - dd if=build/target_mega65/newrom_0 bs=8192 count=1 skip=0 of=$@ + dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=0 of=$@ -build/kernal_hybrid.rom: kernal build/target_generic/OUTK.BIN +build/kernal_hybrid.rom: kernal $(DIR_GENERIC)/OUTK.BIN @echo @echo $(HYBRID_WARNING) @echo (dd if=kernal bs=1140 count=1 skip=0 ; \ echo " > HYBRID ROM, DON'T DISTRIBUTE <" ; \ dd if=kernal bs=1 count=58 skip=1176 ; \ - cat build/target_generic/OUTK.BIN) > $@ + cat $(DIR_GENERIC)/OUTK.BIN) > $@ -build/symbols_hybrid.vs: build/target_generic/KERNAL_combined.vs - sort build/target_generic/KERNAL_combined.vs | uniq | grep -v "__" > $@ +build/symbols_hybrid.vs: $(DIR_GENERIC)/KERNAL_combined.vs + sort $(DIR_GENERIC)/KERNAL_combined.vs | uniq | grep -v "__" > $@ # Rules - platform 'Mega 65' specific -build/mega65.rom: build/kernal_mega65.rom_0 build/target_mega65/kernal.seg_1 build/basic_mega65.rom_0 build/chargen.rom +build/mega65.rom: build/kernal_mega65.rom_0 $(DIR_MEGA65)/kernal.seg_1 build/basic_mega65.rom_0 build/chargen.rom dd if=/dev/zero bs=8192 count=1 of=build/padding_8k dd if=/dev/zero bs=8192 count=8 of=build/padding_64k cat build/padding_8k > build/mega65.rom cat build/padding_8k >> build/mega65.rom - cat build/target_mega65/kernal.seg_1 >> build/mega65.rom + cat $(DIR_MEGA65)/kernal.seg_1 >> build/mega65.rom cat build/padding_8k >> build/mega65.rom cat build/padding_8k >> build/mega65.rom cat build/basic_mega65.rom_0 >> build/mega65.rom @@ -305,6 +321,6 @@ test_m65: build/mega65.rom testremote: build/kernal_custom.rom build/basic_custom.rom build/symbols_custom.vs x64 -kernal build/kernal_custom.rom -basic build/basic_custom.rom -moncommands build/symbols_custom.vs -remotemonitor -testsimilarity: build/target_generic/newrom $(TOOL_SIMILARITY) kernal basic - $(TOOL_SIMILARITY) kernal build/target_generic/newrom - $(TOOL_SIMILARITY) basic build/target_generic/newrom +testsimilarity: $(TOOL_SIMILARITY) $(DIR_GENERIC)/newrom kernal basic + $(TOOL_SIMILARITY) kernal $(DIR_GENERIC)/newrom + $(TOOL_SIMILARITY) basic $(DIR_GENERIC)/newrom diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index b8cfb3c36c64ff2b1d8ea7134e181facfb61d607..92f77191493d587177a780d190d160c826549581 100644 GIT binary patch delta 158 zcmZp0XmFU|q4D_DN_&M%|1(x8Fg#GW_iB+MkX~wa^8W{(Me<GFgw4+U(xfPxB-H!omOV`98F`8Znu%i~uJ36mAsZ6+JAvrUd=KgRfYvkFHg m3*+O-^LTWDe%(4-~pDuLuBo@Ix2? delta 158 zcmZp0XmFU|p|SJTN_&M%|1(x8Fg#G$@@kPHkX~wa^8W{(Me<GFgw4+U(xfPxA;H!omOV`AJg`8Znu%g$E}36mAsZ6+JAvrUd=KgPIovkFHg m3**ko^LTWDgZgN_&M%|1(x8Fg#GW`f8CPkX~wa^8W{(Me<>REZ}2d zyfwL=#f|0uE1#>IPqO@FWV|~0I9mYYt<4hb+>Agp>&{ delta 159 zcmZp0XmFU|p|SbZN_&M%|1(x8Fg#FL_iB+MkX~wa^8W{(Me<AgU5<>0pw>=Jh-J{-Nhe{D4an*{QKo3- z_V&HoeQ)=B?|n}-_8PlmG5yWiCC4#{p}~HVW7uT@Fgh>{ z7XcCe0^a%e4-7V1OBGNQ=}mco?j-5PD#omkpBRgNyGKOFMRZ6;wUekc=F#BT1Eh_> z;bIS*RKv&Js9J%sODAYx*3~71oz&Tnm6TFi(7I{Pt8Q+Y^z^w*K2AJA(Y=-!PuCl0 zK5+nt3#15dD5?rt<>V1<@G9Z;;#dcDfwW#tb{nW?$nIk@a`6U3jjCLcHmatbco1pJdJ)HVYhVYf`7KC(2s zYH8B>y^xjVI`@BCd!F6xU@kYQ$*ZRB8&W0TT$<75Tc4aLl`V(Sdy}Y%{3Cm5$^{wd z42p+DvX>e5$dIvDN64a_#Y>9h?z*zSo$cvCO00W-H@Fs@l+x1vE5@ZA$_y)My_Rv* z8$nAZamtvlB;4l94U;1|3(6-{Aj|>WJ^F+kS3$+L*E9788DNNd#;Ngki}lo?w@+L^ z4+=*3lqZmhoMqEXRkbfqG}D7U2_>&9A{JRr+&iB6v_D1m8#te z>r2l~33}|vF9Rt$rkxu`j>Rn}`Aa~(xB1W2vGyct6g5Dzsl=a5xD0Lz7L&i^EnNtHSAb3a z5={r^2Z%3DCcPUhy%R?q!vewo^E-p}7@x-a2K1hEg% zG4d#XIn9&uf~u*|G)L5?IShRe`l#Q%C0UN-Xu)!=N{3{ipoq}{3ey@f_m5o(xTGZon6gZRugE|}f$P|;py2K1>s~)) zi2!Rwfwe3_)Jfi+_O9t>c=rug;uy-7NN}2sj*w}E7jpW;uFQk!gRXrC&4ai_ymYa@ zqKq_JmXO)gOBh(WVft%^TS43r0xVBYf5X@Tg@A4aQ3uJGQM{-q#5Y*7N-av7s|M-g zz3|itcapr?6oST&KOIF)A^1~)tRuKHOt#D@E9ng2YeDP};@OjUk%awY_)l@X>Mp)1 zVP+KfkKuh$oF?O8;+;`EYmJE4iQ7sv+vaMv&4-Q}#sfiY8gUM~D0YqAA$|Mkoss_n DA9-u4 delta 2302 zcmYjSeNa@_6@TyT7Yi&b-wTM`ibg)7fGA>XBTUDGsXH8`k=g;mT8WfC!9ArlsS@9pl}6?uya+w;~q&Ccw7 z=brcOIp_ZF@BD6Kbz`-?g8ty_>LVKC<^bnLn*+#0zSKOUy(nN8L0WFb+Lh04T3Jp} zEQ^O-)P85mcmkhziW}D5l(lVmmDn~Goac?bX$v*I^a2TMYnXFBvR+qSF%rZ*L3C)+ zuED=ojIy;8-S)f9XnPc=NslHPu-E~!T|dCeOciTki9=VayK;H3s*DWlN~%qMd}FGf zJCDHFsc`3b4c@1q=cmB4H|)OYqR<FVjo4m3~A75vO)i&EX9xf zvrvQ9SKqzVzV%Dgs;)PY_w*JG{>vmeuP<1;$=^edwVbX(&x$U_+JW1Au{qb-OpW#P z*L`PjzmG*tqAP0caJ}-l_|qiau-go+(+6F6sO#GP%ZEGqhHA|_UU*HSbcqb&_SJj zUyduHd991Kdep@y7u?sK@x3pJ$0^!tRyexZK)WdGQM4rFegLZwML%;Crt79q^%Nff zPd6<4<|tr?E2H>l(fu{(t6+V%V|h;#({k5^T0Xa#XV}hjat443r8Fp<2XKv904;91 zOUmPyJC=B&IZao712?lay5@dmA*p$-KQ8B`Ai4T-U0jn&pp^?>kgKUrcbD8KDTX%ZTo zVfWXx)xh7ma<+Ow3BvsO>6Jg!>w?qXP zV2YHxZAQbX{=Pyx<5<4$KR9q7T(aKQRur+SGoORk`%dsWpA##7QkT3WdqM(WpALKK z7$b|$2(bw+55t}hB^Qv1YkdB-F;S!7rCqgj;#wPDW=MotDkz!y76QEF+;cl=q8{NI}# z(8#e}?O?1&aAg>d7&j{45-y3~{7Z(YMG*>c$+92p|S*tpnsCg>UKv zwZL!tDRhFYNvmBGOP&EIZauf}nuv{?k$KJa?Qy@=ywaK zfqam*Ca%>FY6BfWLTPIaTm3-0D*`D^uUM@}{kF1yoE;cIveLh=A5!xUN=Q$t4-C1Yj{F zx4>m$J?vnin}APGWqriV3M7*Cl)9qI^4xlFz+H__`+@5AMd!znz2am$cLg+Wn)^f@ zo7&-}JrlGD9(pt-;7bv%3q|N`foQNT#~&dA9^1Y003X-=Q@CV z22lAL{L!4#;G*DT^7rgDD3i~WH9G@2O!s92INh1{B=w>Hf2N1oE9h0E zIA@t!_X{~?s?z^C=Qr`!BpeDM_5oT=9_Fm0H;~HQ+AO%OCe_<&{LuwA;@TeTP;xkT zomN#VGMu}FnVTh%+`OL;3r+)X;5uXtDh_a+wbo9z9#jgidZ_LJ)N(`}z2>i8j7fz# z4uq^s15yD>;rjxQ1d%Y^`GseMGKcysa@cc=G7IPcd3Dj7@jbzYo6hJFG%XTgQ8|5; zEXuo7lc6|M4knE{_Z~Ej;yt4EI7`yvj7bOomYR1wrA5>D&Y^VEzX#jwJL~FqejOUV zR#<_G3*Hh0QM_|U6lM5{!C>TmfGk^F$Ux*Ri+^hH2)I3f2syR*Wn+5)2<;J2J4wzj zC{_Gii#fH(EGIe}k$&C_e;a>CRWd{Za6{vdr@(;QA6X`Gbe3$-FDsPh@i`wpBj9BV zSS#U?8GK+KZ@7y;lrS@e2WRl!FrJX`zlbNlU}=_!k+`c+v#VIM>q!mX7{uKIj-Pal QIw^Kz^)IEbAL`}*0i4=w5C8xG diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index 851c2b6df83a1220d9f9ba8ee4dbc72b620540a9..eb9aa28f3aa6cf4c2d03ea8c7f5b2c158c3344c2 100644 GIT binary patch delta 14 VcmZp0XmHqYl!eh^^D!1HX#gpN1qA>A delta 14 VcmZp0XmHqYl!eiJ^D!1HX#gpH1q1*9 diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index 194dad408a52855eefe681c180820618c5f795e9..eafc1352e8c635f77ce252d4210dd9151ddeb221 100644 GIT binary patch delta 2177 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 diff --git a/bin/mega65.rom b/bin/mega65.rom index 311197a33b66647ebf1725630031564b8a94dd83..8e2131896af2d08df42e97ed903111d013b1e208 100644 GIT binary patch delta 4946 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 QBlO*|i6j5~RdNsfKaEPj$N&HU delta 3451 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 diff --git a/doc/Development.md b/doc/Development.md index 24760240..427a037b 100644 --- a/doc/Development.md +++ b/doc/Development.md @@ -139,7 +139,7 @@ This is a very common one. For standard ROM layout just take the file. For non-s // #LAYOUT# * * #IGNORE ``` -This can be found in a private (internal) jumptable of `KERNAL_1` segmment of `M65` layout. For standard ROM part (`KERNAL_0` segment) take it as floating routine (for `KERNAL_0` segment the file provides only labels for the jumptable). For `KERNAL_1` segment of `M65` layout, take it as a fixed location-routine; in such case the file will provide a jumptable itself. For memory layout other than `M65`, just ignore the file. Yet another example: +This can be found in a private (internal) vector table of `KERNAL_1` segment of `M65` layout. For standard ROM part (`KERNAL_0` segment) take it as floating routine (for `KERNAL_0` segment the file provides only labels for the vector table). For `KERNAL_1` segment of `M65` layout, take it as a fixed location-routine; in such case the file will provide a vector table itself. For memory layout other than `M65`, just ignore the file. Yet another example: ``` // #LAYOUT# M65 KERNAL_0 #TAKE @@ -155,16 +155,16 @@ This is used for memory mapping helper routines, which are only needed for Mega6 // #LAYOUT# * * #IGNORE ``` -This is for the routine, that on Mega65 goes to `KERNAL_1` segment, but can still be transparently called using fixed location in `KERNAL_0` segement. The code might, for example, look this way: +This is for the routine, that on Mega65 goes to `KERNAL_1` segment, but can still be transparently called using fixed location in `KERNAL_0` segment. The code might, for example, look this way: ``` ROUTINE_NAME: #if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) - jsr map_KERNAL_1 - jsr KERNAL_1__ROUTINE_NAME // execute routine from KERNAL_1 segment - jmp map_NORMAL + jsr map_KERNAL_1 + jsr_ind VK1__ROUTINE_NAME // execute routine from KERNAL_1 segment + jmp map_NORMAL #else From f9f13f8334676be115778990589c403c76fda148 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 18:33:52 +0100 Subject: [PATCH 15/66] added first stubs for math routines --- Makefile | 1 + STATUS.md | 51 ++++++++++++++++++++++++++++- c64/basic/,stubs_math/ba8c.CONUPK.s | 24 ++++++++++++++ c64/basic/,stubs_math/ba8c.interop | 3 ++ c64/basic/,stubs_math/bba2.MOVFM.s | 25 ++++++++++++++ c64/basic/,stubs_math/bba2.interop | 3 ++ c64/basic/,stubs_math/bbd4.MOVMF.s | 24 ++++++++++++++ c64/basic/,stubs_math/bbd4.interop | 3 ++ c64/basic/,stubs_math/bbfc.MOVEF.s | 17 ++++++++++ c64/basic/,stubs_math/bbfc.interop | 3 ++ c64/basic/,stubs_math/bc0f.MOVFA.s | 17 ++++++++++ c64/basic/,stubs_math/bc0f.interop | 3 ++ 12 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 c64/basic/,stubs_math/ba8c.CONUPK.s create mode 100644 c64/basic/,stubs_math/ba8c.interop create mode 100644 c64/basic/,stubs_math/bba2.MOVFM.s create mode 100644 c64/basic/,stubs_math/bba2.interop create mode 100644 c64/basic/,stubs_math/bbd4.MOVMF.s create mode 100644 c64/basic/,stubs_math/bbd4.interop create mode 100644 c64/basic/,stubs_math/bbfc.MOVEF.s create mode 100644 c64/basic/,stubs_math/bbfc.interop create mode 100644 c64/basic/,stubs_math/bc0f.MOVFA.s create mode 100644 c64/basic/,stubs_math/bc0f.interop diff --git a/Makefile b/Makefile index 439cf4d0..45114ca3 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ SRCDIR_COMMON = c64/aliases SRCDIR_BASIC = $(SRCDIR_COMMON) \ c64/basic \ c64/basic/,stubs \ + c64/basic/,stubs_math \ c64/basic/commands \ c64/basic/init \ c64/basic/rom_revision diff --git a/STATUS.md b/STATUS.md index d1cdaa6c..76fbb50e 100644 --- a/STATUS.md +++ b/STATUS.md @@ -144,7 +144,56 @@ For the current status of the low memory location implementation andd usage chec
-### Unofficial BASIC routines/locations + +### Math package + +Floating point mathematical routines - not official, but well known and broadly used. + +
+ +| Address | Name | Status | Remarks | +| :-------: | :----------- | :------: | :------------------------------------------------: | +| `$B1AA` | `FACINX` | NOT DONE | XXX - no stub added yet | +| `$B391` | `GIVAYF` | NOT DONE | XXX - no stub added yet | +| `$B7B5` | `STRVAL` | NOT DONE | XXX - no stub added yet | +| `$B850` | `FSUB` | NOT DONE | XXX - no stub added yet | +| `$B853` | `FSUBT` | NOT DONE | XXX - no stub added yet | +| `$B867` | `FADD` | NOT DONE | XXX - no stub added yet | +| `$B86A` | `FADDT` | NOT DONE | XXX - no stub added yet | +| `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | +| `$BA28` | `FMULT` | NOT DONE | XXX - no stub added yet | +| `$BA8C` | `CONUPK` | NOT DONE | fetch FAC2 from RAM location | +| `$BAE2` | `MUL10` | NOT DONE | XXX - no stub added yet | +| `$BAFE` | `DIV10` | NOT DONE | XXX - no stub added yet | +| `$BB0F` | `FDIV` | NOT DONE | XXX - no stub added yet | +| `$BB12` | `FDIVT` | NOT DONE | XXX - no stub added yet | +| `$BBA2` | `MOVFM` | NOT DONE | fetch FAC1 from RAM location | +| `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | +| `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | +| `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | +| `$BC2B` | `SIGN` | NOT DONE | XXX - no stub added yet | +| `$BC39` | `SGN` | NOT DONE | XXX - no stub added yet | +| `$BC58` | `ABS` | NOT DONE | XXX - no stub added yet | +| `$BC5B` | `FCOMP` | NOT DONE | XXX - no stub added yet | +| `$BC9B` | `QINT` | NOT DONE | XXX - no stub added yet | +| `$BCCC` | `INT` | NOT DONE | XXX - no stub added yet | +| `$BCF3` | `FIN` | NOT DONE | XXX - no stub added yet | +| `$BDDD` | `FOUT` | NOT DONE | XXX - no stub added yet | +| `$BF71` | `SQR` | NOT DONE | XXX - no stub added yet | +| `$BF78` | `FPWR` | NOT DONE | XXX - no stub added yet | +| `$BF7B` | `FPWRT` | NOT DONE | XXX - no stub added yet | +| `$BFB4` | `NEGOP` | NOT DONE | XXX - no stub added yet | +| `$BFED` | `EXP` | NOT DONE | XXX - no stub added yet | +| `$E043` | `POLY1` | NOT DONE | XXX - no stub added yet | +| `$E059` | `POLY2` | NOT DONE | XXX - no stub added yet | +| `$E264` | `COS` | NOT DONE | XXX - no stub added yet | +| `$E26B` | `SIN` | NOT DONE | XXX - no stub added yet | +| `$E2B4` | `TAN` | NOT DONE | XXX - no stub added yet | +| `$E30E` | `ATN` | NOT DONE | XXX - no stub added yet | + +
+ +### Other unofficial BASIC routines/locations Not all of them - only these we want to have implemented. diff --git a/c64/basic/,stubs_math/ba8c.CONUPK.s b/c64/basic/,stubs_math/ba8c.CONUPK.s new file mode 100644 index 00000000..f31ee902 --- /dev/null +++ b/c64/basic/,stubs_math/ba8c.CONUPK.s @@ -0,0 +1,24 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - fetch FAC2 from RAM location +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// Output: +// - .A - FAC1 exponent (XXX really FAC1?) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +CONUPK: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba8c.interop b/c64/basic/,stubs_math/ba8c.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/ba8c.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bba2.MOVFM.s b/c64/basic/,stubs_math/bba2.MOVFM.s new file mode 100644 index 00000000..8be43857 --- /dev/null +++ b/c64/basic/,stubs_math/bba2.MOVFM.s @@ -0,0 +1,25 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC1 to memory location, rounds if asked +// +// Input: +// - .X - address low byte +// - .Y - address high byte +// - $70 - if MSB is set performs rouding +// +// Output: +// - .A - FAC1 exponent +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +MOVMF: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bba2.interop b/c64/basic/,stubs_math/bba2.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bba2.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bbd4.MOVMF.s b/c64/basic/,stubs_math/bbd4.MOVMF.s new file mode 100644 index 00000000..a144da44 --- /dev/null +++ b/c64/basic/,stubs_math/bbd4.MOVMF.s @@ -0,0 +1,24 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - fetch FAC1 from RAM location +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// Output: +// - .A - FAC1 exponent, affects status flags +// - .Y - always 0 +// +// See also: +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +MOVFM: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bbd4.interop b/c64/basic/,stubs_math/bbd4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bbd4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bbfc.MOVEF.s b/c64/basic/,stubs_math/bbfc.MOVEF.s new file mode 100644 index 00000000..b04de5b6 --- /dev/null +++ b/c64/basic/,stubs_math/bbfc.MOVEF.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC2 to FAC1 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +MOVEF: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bbfc.interop b/c64/basic/,stubs_math/bbfc.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bbfc.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc0f.MOVFA.s b/c64/basic/,stubs_math/bc0f.MOVFA.s new file mode 100644 index 00000000..fbc9087e --- /dev/null +++ b/c64/basic/,stubs_math/bc0f.MOVFA.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC1 to FAC2, skips rounding +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +MOVFA: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc0f.interop b/c64/basic/,stubs_math/bc0f.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc0f.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example From 1b49724c505f5b21c40e03ade727f02bdb16111c Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 18:37:19 +0100 Subject: [PATCH 16/66] small fix for vector alignment problem --- c64/kernal/screen/chrout_screen_jumptable_codes.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c64/kernal/screen/chrout_screen_jumptable_codes.s b/c64/kernal/screen/chrout_screen_jumptable_codes.s index 499ed5ed..a3dc700d 100644 --- a/c64/kernal/screen/chrout_screen_jumptable_codes.s +++ b/c64/kernal/screen/chrout_screen_jumptable_codes.s @@ -93,7 +93,7 @@ chrout_screen_jumptable_hi: #else -.if (mod(*, $2) == 1) { nop } // align code so that vector never crosses page boundary +.if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary chrout_screen_jumptable: @@ -120,6 +120,6 @@ chrout_screen_jumptable: .word chrout_screen_DEL .word chrout_screen_RETURN -.if (mod(*, $2) == 1) { nop } // make sure routine size is always the same, needed by build system +.if (mod(*, $2) == 0) { brk } // make sure routine size is always the same, needed by build system #endif From dff590c9792dd23348674444a0f2cfcead5e4cea Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 19:45:02 +0100 Subject: [PATCH 17/66] Kernal size optimizations --- STATUS.md | 47 ++++++--- .../banking/4000.mega65_vectable_kernal_1.s | 12 ++- c64/kernal/banking/mega65_imports.s | 9 ++ c64/kernal/errors.s | 96 ++++++++----------- c64/kernal/init/e5a0.setup_vicii.s | 13 ++- c64/kernal/init/fda3.ioinit.s | 14 ++- c64/kernal/status.s | 42 ++++++++ 7 files changed, 161 insertions(+), 72 deletions(-) create mode 100644 c64/kernal/status.s diff --git a/STATUS.md b/STATUS.md index 76fbb50e..399d06c6 100644 --- a/STATUS.md +++ b/STATUS.md @@ -50,29 +50,41 @@ The following ROM features are currently missing: ## Keyboard +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | | C64 | DONE | | | C128 | DONE | | | Mega65 | NOT DONE | code should be complete, but is not tested yet | +
+ ## Screen +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | | VIC-II | DONE | | | 80 columns, VDC | NOT DONE | | | 80 columns, Mega65 | NOT DONE | | +
+ ## Tape port (LOAD only!) * Tapuino * Datasette +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | -| normal | DONE | | -| turbo (250 blocks) | DONE | | +| normal | DONE | up to 202 blocks, like original ROM | +| turbo | DONE | up to 250 blocks, like the best implementations | + +
## IEC bus @@ -81,6 +93,8 @@ The following ROM features are currently missing: * most disk drives and printers * some hard drives +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | | standard | DONE | | @@ -89,27 +103,36 @@ The following ROM features are currently missing: | CIA burst mod | NOT DONE | | | Mega65 burst | NOT DONE | | +
+ ## IEEE-488 bus * petSD+ * PET era disk drives and printers * various scientific equipment +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | | CBM cartridge | NOT DONE | | +
+ ## RS-232 * modems (telephone, WiFi) * parallel port printers +
+ | Driver | Status | Remarks | | :----------------: | :------: | :------------------------------------------------: | | UP2400 | NOT DONE | | | UP9600 | NOT DONE | work started, not functional yet | | ACIA 6551 | NOT DONE | | +
# API status @@ -202,19 +225,19 @@ Not all of them - only these we want to have implemented. | Address | Name | Status | Remarks | | :-------: | :----------- | :------: | :------------------------------------------------: | | `$A004` | revision str | DONE | | -| `$A408` | REASON | NOT DONE | | +| `$A408` | `REASON` | NOT DONE | | | `$A453` | (unknown) | NOT DONE | | -| `$A533` | LINKPRG | DONE | | +| `$A533` | `LINKPRG` | DONE | | | `$A644` | new | NOT DONE | | | `$A659` | set txt ptr | NOT DONE | | -| `$A68E` | RUNC | DONE | | -| `$A7AE` | NEWSTT | PARTIAL | redirected to RUN command | -| `$AB1E` | STROUT | DONE | | -| `$AD9E` | FRMEVL | NOT DONE | | -| `$BDCD` | LINPRT | DONE | temporary implementation | -| `$E3BF` | INIT | NOT DONE | | -| `$E422` | INITMSG | DONE | | -| `$E453` | RVECT | NOT DONE | | +| `$A68E` | `RUNC` | DONE | | +| `$A7AE` | `NEWSTT` | PARTIAL | redirected to RUN command | +| `$AB1E` | `STROUT` | DONE | | +| `$AD9E` | `FRMEVL` | NOT DONE | | +| `$BDCD` | `LINPRT` | DONE | temporary implementation | +| `$E3BF` | `INIT` | NOT DONE | | +| `$E422` | `INITMSG` | DONE | | +| `$E453` | `RVECT` | NOT DONE | |
diff --git a/c64/kernal/banking/4000.mega65_vectable_kernal_1.s b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s index 775c1f93..6c865009 100644 --- a/c64/kernal/banking/4000.mega65_vectable_kernal_1.s +++ b/c64/kernal/banking/4000.mega65_vectable_kernal_1.s @@ -11,16 +11,20 @@ // Label definitions - .label VK1__RAMTAS = $4000 + 2 * 0 - .label VK1__load_tape_normal = $4000 + 2 * 1 - .label VK1__load_tape_turbo = $4000 + 2 * 2 - .label VK1__load_tape_auto = $4000 + 2 * 3 + .label VK1__IOINIT = $4000 + 2 * 0 + .label VK1__RAMTAS = $4000 + 2 * 1 + .label VK1__setup_vicii = $4000 + 2 * 2 + .label VK1__load_tape_normal = $4000 + 2 * 3 + .label VK1__load_tape_turbo = $4000 + 2 * 4 + .label VK1__load_tape_auto = $4000 + 2 * 5 #else // Vector table (OpenROMs private!) + .word IOINIT .word RAMTAS + .word setup_vicii #if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_AUTODETECT .word load_tape_normal diff --git a/c64/kernal/banking/mega65_imports.s b/c64/kernal/banking/mega65_imports.s index 3cc727e6..8546e2ce 100644 --- a/c64/kernal/banking/mega65_imports.s +++ b/c64/kernal/banking/mega65_imports.s @@ -9,11 +9,20 @@ .label STOP = KERNAL_0.STOP +.label clrchn_reset = KERNAL_0.clrchn_reset .label udtim_keyboard = KERNAL_0.udtim_keyboard +.label setup_irq_timer = KERNAL_0.setup_irq_timer .label wait_x_bars = KERNAL_0.wait_x_bars +#if CONFIG_IEC + +.label iec_set_idle = KERNAL_0.iec_set_idle + +#endif + + #if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO .label screen_on = KERNAL_0.screen_on diff --git a/c64/kernal/errors.s b/c64/kernal/errors.s index 91a85fe0..e1642238 100644 --- a/c64/kernal/errors.s +++ b/c64/kernal/errors.s @@ -6,90 +6,78 @@ // Kernal error codes are described in 'Commodore 64 Programmers Reference Guide', page 306 kernalerror_ROUTINE_TERMINATED: // by a STOP key + lda #K_ERR_ROUTINE_TERMINATED - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_TOO_MANY_OPEN_FILES: + lda #K_ERR_TOO_MANY_OPEN_FILES - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_ALREADY_OPEN: + lda #K_ERR_FILE_ALREADY_OPEN - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_NOT_OPEN: + lda #K_ERR_FILE_NOT_OPEN - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_NOT_FOUND: + lda #K_ERR_FILE_NOT_FOUND - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_DEVICE_NOT_FOUND: + lda #K_ERR_DEVICE_NOT_FOUND - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_NOT_INPUT: + lda #K_ERR_FILE_NOT_INPUT - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_NOT_OUTPUT: + lda #K_ERR_FILE_NOT_OUTPUT - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_FILE_NAME_MISSING: + lda #K_ERR_FILE_NAME_MISSING - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_ILLEGAL_DEVICE_NUMBER: + lda #K_ERR_ILLEGAL_DEVICE_NUMBER - sec - rts + skip_2_bytes_trash_nvz + + // FALLTROUGH kernalerror_TOP_MEM_RS232: + lda #K_ERR_TOP_MEM_RS232 + sec rts - - -// Kernal status codes are described in 'Commodore 64 Programmers Reference Guide', page 292 - -kernalstatus_reset: - lda #$00 - sta IOSTATUS - rts - -// The following two statuses are currently not implemented - and most likely not really needed - -// kernalstatus_TIMEOUT_WRITE: -// lda IOSTATUS -// ora #K_STS_TIMEOUT_WRITE -// sta IOSTATUS -// rts - -// kernalstatus_TIMEOUT_READ: -// lda IOSTATUS -// ora #K_STS_TIMEOUT_READ -// sta IOSTATUS -// rts - -kernalstatus_EOI: - lda IOSTATUS - ora #K_STS_EOI - sta IOSTATUS - rts - -kernalstatus_DEVICE_NOT_FOUND: - lda IOSTATUS - ora #K_STS_DEVICE_NOT_FOUND - sta IOSTATUS - rts diff --git a/c64/kernal/init/e5a0.setup_vicii.s b/c64/kernal/init/e5a0.setup_vicii.s index a7a3e4f4..28cc6bf9 100644 --- a/c64/kernal/init/e5a0.setup_vicii.s +++ b/c64/kernal/init/e5a0.setup_vicii.s @@ -1,5 +1,6 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT // #LAYOUT# * * #IGNORE // @@ -11,6 +12,14 @@ setup_vicii: +#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) + + jsr map_KERNAL_1 + jsr_ind VK1__setup_vicii + jmp map_NORMAL + +#else + // Clear everything - turn off sprites (observed hanging around after // running programs and resetting), etc. @@ -67,3 +76,5 @@ setup_vicii: // Setup default I/O devices jmp clrchn_reset + +#endif // ROM layout diff --git a/c64/kernal/init/fda3.ioinit.s b/c64/kernal/init/fda3.ioinit.s index e0fa1ecd..72582f05 100644 --- a/c64/kernal/init/fda3.ioinit.s +++ b/c64/kernal/init/fda3.ioinit.s @@ -1,5 +1,6 @@ // #LAYOUT# STD * #TAKE -// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_0 #TAKE +// #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT // #LAYOUT# * * #IGNORE // @@ -14,6 +15,14 @@ IOINIT: +#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0) + + jsr map_KERNAL_1 + jsr_ind VK1__IOINIT + jmp map_NORMAL + +#else + // // First initialize the CPU port, to make sure we have correct memory map // @@ -146,3 +155,6 @@ IOINIT: rts #endif + + +#endif // ROM layout diff --git a/c64/kernal/status.s b/c64/kernal/status.s new file mode 100644 index 00000000..39747d00 --- /dev/null +++ b/c64/kernal/status.s @@ -0,0 +1,42 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + + +// Kernal status codes are described in 'Commodore 64 Programmers Reference Guide', page 292 + +kernalstatus_reset: + lda #$00 + beq kernalstatus_end // branch always + +// The following two statuses are currently not implemented - and most likely not really needed + +// kernalstatus_TIMEOUT_WRITE: +// +// lda IOSTATUS +// ora #K_STS_TIMEOUT_WRITE +// bne kernalstatus_end // branch always + +// kernalstatus_TIMEOUT_READ: +// +// lda IOSTATUS +// ora #K_STS_TIMEOUT_READ +// bne kernalstatus_end // branch always + +kernalstatus_EOI: + + lda IOSTATUS + ora #K_STS_EOI + bne kernalstatus_end // branch always + +kernalstatus_DEVICE_NOT_FOUND: + + lda IOSTATUS + ora #K_STS_DEVICE_NOT_FOUND + + // FALLTROUGH + +kernalstatus_end: + + sta IOSTATUS + rts From ee9bda865293baa8cf563a07bff69c182e6393cd Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 28 Jan 2020 20:03:12 +0100 Subject: [PATCH 18/66] more Mega65 size optimizations --- Makefile | 15 ++++++++------- c64/basic/init/e394.basic_cold_start.s | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 45114ca3..84736f02 100644 --- a/Makefile +++ b/Makefile @@ -179,15 +179,16 @@ $(DIR_ULTIMATE64)/newrom: $(DIR_ULTIMATE64)/OUTB.BIN $(DIR_ULTIMATE6 build/kernal_custom.rom: $(DIR_CUSTOM)/newrom build/kernal_generic.rom: $(DIR_GENERIC)/newrom build/kernal_testing.rom: $(DIR_TESTING)/newrom -build/kernal_mega65.rom_0: $(DIR_MEGA65)/newrom_0 build/kernal_ultimate64.rom: $(DIR_ULTIMATE64)/newrom build/basic_custom.rom: $(DIR_CUSTOM)/newrom build/basic_generic.rom: $(DIR_GENERIC)/newrom build/basic_testing.rom: $(DIR_TESTING)/newrom -build/basic_mega65.rom_0: $(DIR_MEGA65)/newrom_0 build/basic_ultimate64.rom: $(DIR_ULTIMATE64)/newrom +$(DIR_MEGA65)/kernal.seg_0: $(DIR_MEGA65)/newrom_0 +$(DIR_MEGA65)/basic.seg_0: $(DIR_MEGA65)/newrom_0 + build/symbols_custom.vs: $(DIR_CUSTOM)/BASIC_combined.vs $(DIR_CUSTOM)/KERNAL_combined.vs build/symbols_generic.vs: $(DIR_GENERIC)/BASIC_combined.vs $(DIR_GENERIC)/KERNAL_combined.vs build/symbols_testing.vs: $(DIR_TESTING)/BASIC_combined.vs $(DIR_TESTING)/KERNAL_combined.vs @@ -246,10 +247,10 @@ build/symbols_%.vs: $(DIR_MEGA65)/newrom_0: cat $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN > $@ -build/kernal_mega65.rom_0: +$(DIR_MEGA65)/kernal.seg_0: dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=2 of=$@ -build/basic_mega65.rom_0: +$(DIR_MEGA65)/basic.seg_0: dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=0 of=$@ build/kernal_hybrid.rom: kernal $(DIR_GENERIC)/OUTK.BIN @@ -266,7 +267,7 @@ build/symbols_hybrid.vs: $(DIR_GENERIC)/KERNAL_combined.vs # Rules - platform 'Mega 65' specific -build/mega65.rom: build/kernal_mega65.rom_0 $(DIR_MEGA65)/kernal.seg_1 build/basic_mega65.rom_0 build/chargen.rom +build/mega65.rom: $(DIR_MEGA65)/basic.seg_0 $(DIR_MEGA65)/kernal.seg_0 $(DIR_MEGA65)/kernal.seg_1 build/chargen.rom dd if=/dev/zero bs=8192 count=1 of=build/padding_8k dd if=/dev/zero bs=8192 count=8 of=build/padding_64k cat build/padding_8k > build/mega65.rom @@ -274,9 +275,9 @@ build/mega65.rom: build/kernal_mega65.rom_0 $(DIR_MEGA65)/kernal.seg_1 build/bas cat $(DIR_MEGA65)/kernal.seg_1 >> build/mega65.rom cat build/padding_8k >> build/mega65.rom cat build/padding_8k >> build/mega65.rom - cat build/basic_mega65.rom_0 >> build/mega65.rom + cat $(DIR_MEGA65)/basic.seg_0 >> build/mega65.rom cat build/chargen.rom build/chargen.rom >> build/mega65.rom - cat build/kernal_mega65.rom_0 >> build/mega65.rom + cat $(DIR_MEGA65)/kernal.seg_0 >> build/mega65.rom cat build/padding_64k >> build/mega65.rom rm -f build/padding* diff --git a/c64/basic/init/e394.basic_cold_start.s b/c64/basic/init/e394.basic_cold_start.s index c1ada5f1..670cdda6 100644 --- a/c64/basic/init/e394.basic_cold_start.s +++ b/c64/basic/init/e394.basic_cold_start.s @@ -8,7 +8,7 @@ basic_cold_start: -// #if !ROM_LAYOUT_M65 +#if !ROM_LAYOUT_M65 // can be safely skipped in Mega65 ROM layout // Before doing anything, check if we have a compatible BASIC/KERNAL pair @@ -24,7 +24,7 @@ basic_cold_start: dey bpl !-- -// #endif +#endif // Remaining part would not fit here From 9de9a6c0a707ce3b38c0170fdca72b7a359868e5 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 18:24:31 +0100 Subject: [PATCH 19/66] several more stubs for math routines --- STATUS.md | 41 +++++++++++++++-------------- c64/basic/,stubs_math/b1aa.FACINX.s | 20 ++++++++++++++ c64/basic/,stubs_math/b1aa.interop | 3 +++ c64/basic/,stubs_math/b850.FSUB.s | 21 +++++++++++++++ c64/basic/,stubs_math/b850.interop | 3 +++ c64/basic/,stubs_math/b853.FSUBT.s | 23 ++++++++++++++++ c64/basic/,stubs_math/b853.interop | 3 +++ c64/basic/,stubs_math/b867.FADD.s | 21 +++++++++++++++ c64/basic/,stubs_math/b867.interop | 3 +++ c64/basic/,stubs_math/b86a.FADDT.s | 23 ++++++++++++++++ c64/basic/,stubs_math/b86a.interop | 3 +++ c64/basic/,stubs_math/ba28.FMUL.s | 24 +++++++++++++++++ c64/basic/,stubs_math/ba28.interop | 3 +++ c64/basic/,stubs_math/ba2b.FMULT.s | 23 ++++++++++++++++ c64/basic/,stubs_math/ba2b.interop | 3 +++ c64/basic/,stubs_math/bae2.MUL10.s | 17 ++++++++++++ c64/basic/,stubs_math/bae2.interop | 3 +++ c64/basic/,stubs_math/bafe.DIV10.s | 21 +++++++++++++++ c64/basic/,stubs_math/bafe.interop | 3 +++ c64/basic/,stubs_math/bb0f.FDIV.c | 21 +++++++++++++++ c64/basic/,stubs_math/bb0f.interop | 3 +++ c64/basic/,stubs_math/bb12.FDIVT.s | 23 ++++++++++++++++ c64/basic/,stubs_math/bb12.interop | 3 +++ c64/basic/,stubs_math/bc2b.SIGN.s | 20 ++++++++++++++ c64/basic/,stubs_math/bc2b.interop | 3 +++ c64/basic/,stubs_math/bc5b.FCOMP.s | 28 ++++++++++++++++++++ c64/basic/,stubs_math/bc5b.interop | 3 +++ c64/basic/,stubs_math/bf78.FPWR.s | 21 +++++++++++++++ c64/basic/,stubs_math/bf78.interop | 3 +++ c64/basic/,stubs_math/bf7b.FPWRT.s | 24 +++++++++++++++++ c64/basic/,stubs_math/bf7b.interop | 3 +++ c64/basic/,stubs_math/bfb4.NEGOP.s | 16 +++++++++++ c64/basic/,stubs_math/bfb4.interop | 3 +++ c64/basic/,stubs_math/e043.POLY1.s | 27 +++++++++++++++++++ c64/basic/,stubs_math/e043.interop | 3 +++ c64/basic/,stubs_math/e059.POLY2.s | 27 +++++++++++++++++++ c64/basic/,stubs_math/e059.interop | 3 +++ c64/basic/,stubs_math/e264.COS.s | 17 ++++++++++++ c64/basic/,stubs_math/e264.interop | 3 +++ c64/basic/,stubs_math/e26b.SIN.s | 17 ++++++++++++ c64/basic/,stubs_math/e26b.interop | 3 +++ c64/basic/,stubs_math/e2b4.TAN.s | 17 ++++++++++++ c64/basic/,stubs_math/e2b4.interop | 3 +++ 43 files changed, 535 insertions(+), 20 deletions(-) create mode 100644 c64/basic/,stubs_math/b1aa.FACINX.s create mode 100644 c64/basic/,stubs_math/b1aa.interop create mode 100644 c64/basic/,stubs_math/b850.FSUB.s create mode 100644 c64/basic/,stubs_math/b850.interop create mode 100644 c64/basic/,stubs_math/b853.FSUBT.s create mode 100644 c64/basic/,stubs_math/b853.interop create mode 100644 c64/basic/,stubs_math/b867.FADD.s create mode 100644 c64/basic/,stubs_math/b867.interop create mode 100644 c64/basic/,stubs_math/b86a.FADDT.s create mode 100644 c64/basic/,stubs_math/b86a.interop create mode 100644 c64/basic/,stubs_math/ba28.FMUL.s create mode 100644 c64/basic/,stubs_math/ba28.interop create mode 100644 c64/basic/,stubs_math/ba2b.FMULT.s create mode 100644 c64/basic/,stubs_math/ba2b.interop create mode 100644 c64/basic/,stubs_math/bae2.MUL10.s create mode 100644 c64/basic/,stubs_math/bae2.interop create mode 100644 c64/basic/,stubs_math/bafe.DIV10.s create mode 100644 c64/basic/,stubs_math/bafe.interop create mode 100644 c64/basic/,stubs_math/bb0f.FDIV.c create mode 100644 c64/basic/,stubs_math/bb0f.interop create mode 100644 c64/basic/,stubs_math/bb12.FDIVT.s create mode 100644 c64/basic/,stubs_math/bb12.interop create mode 100644 c64/basic/,stubs_math/bc2b.SIGN.s create mode 100644 c64/basic/,stubs_math/bc2b.interop create mode 100644 c64/basic/,stubs_math/bc5b.FCOMP.s create mode 100644 c64/basic/,stubs_math/bc5b.interop create mode 100644 c64/basic/,stubs_math/bf78.FPWR.s create mode 100644 c64/basic/,stubs_math/bf78.interop create mode 100644 c64/basic/,stubs_math/bf7b.FPWRT.s create mode 100644 c64/basic/,stubs_math/bf7b.interop create mode 100644 c64/basic/,stubs_math/bfb4.NEGOP.s create mode 100644 c64/basic/,stubs_math/bfb4.interop create mode 100644 c64/basic/,stubs_math/e043.POLY1.s create mode 100644 c64/basic/,stubs_math/e043.interop create mode 100644 c64/basic/,stubs_math/e059.POLY2.s create mode 100644 c64/basic/,stubs_math/e059.interop create mode 100644 c64/basic/,stubs_math/e264.COS.s create mode 100644 c64/basic/,stubs_math/e264.interop create mode 100644 c64/basic/,stubs_math/e26b.SIN.s create mode 100644 c64/basic/,stubs_math/e26b.interop create mode 100644 c64/basic/,stubs_math/e2b4.TAN.s create mode 100644 c64/basic/,stubs_math/e2b4.interop diff --git a/STATUS.md b/STATUS.md index 399d06c6..ec4a88fe 100644 --- a/STATUS.md +++ b/STATUS.md @@ -176,42 +176,43 @@ Floating point mathematical routines - not official, but well known and broadly | Address | Name | Status | Remarks | | :-------: | :----------- | :------: | :------------------------------------------------: | -| `$B1AA` | `FACINX` | NOT DONE | XXX - no stub added yet | +| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | | `$B391` | `GIVAYF` | NOT DONE | XXX - no stub added yet | | `$B7B5` | `STRVAL` | NOT DONE | XXX - no stub added yet | -| `$B850` | `FSUB` | NOT DONE | XXX - no stub added yet | -| `$B853` | `FSUBT` | NOT DONE | XXX - no stub added yet | -| `$B867` | `FADD` | NOT DONE | XXX - no stub added yet | -| `$B86A` | `FADDT` | NOT DONE | XXX - no stub added yet | +| `$B850` | `FSUB` | NOT DONE | subtract FAC1 from RAM | +| `$B853` | `FSUBT` | NOT DONE | subtract FAC1 from FAC2 | +| `$B867` | `FADD` | NOT DONE | add RAM to FAC1 | +| `$B86A` | `FADDT` | NOT DONE | add FAC2 to FAC1 | | `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | -| `$BA28` | `FMULT` | NOT DONE | XXX - no stub added yet | +| `$BA28` | `FMUL` | NOT DONE | multiplies FAC1 by RAM | +| `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | | `$BA8C` | `CONUPK` | NOT DONE | fetch FAC2 from RAM location | -| `$BAE2` | `MUL10` | NOT DONE | XXX - no stub added yet | -| `$BAFE` | `DIV10` | NOT DONE | XXX - no stub added yet | -| `$BB0F` | `FDIV` | NOT DONE | XXX - no stub added yet | -| `$BB12` | `FDIVT` | NOT DONE | XXX - no stub added yet | +| `$BAE2` | `MUL10` | NOT DONE | multiply FAC1 by 10 | +| `$BAFE` | `DIV10` | NOT DONE | divide FAC1 by 10, result is always positive | +| `$BB0F` | `FDIV` | NOT DONE | divide RAM by FAC1 | +| `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | | `$BBA2` | `MOVFM` | NOT DONE | fetch FAC1 from RAM location | | `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | | `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | | `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | -| `$BC2B` | `SIGN` | NOT DONE | XXX - no stub added yet | +| `$BC2B` | `SIGN` | NOT DONE | evaluate FAC1 sign | | `$BC39` | `SGN` | NOT DONE | XXX - no stub added yet | | `$BC58` | `ABS` | NOT DONE | XXX - no stub added yet | -| `$BC5B` | `FCOMP` | NOT DONE | XXX - no stub added yet | +| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | | `$BC9B` | `QINT` | NOT DONE | XXX - no stub added yet | | `$BCCC` | `INT` | NOT DONE | XXX - no stub added yet | | `$BCF3` | `FIN` | NOT DONE | XXX - no stub added yet | | `$BDDD` | `FOUT` | NOT DONE | XXX - no stub added yet | | `$BF71` | `SQR` | NOT DONE | XXX - no stub added yet | -| `$BF78` | `FPWR` | NOT DONE | XXX - no stub added yet | -| `$BF7B` | `FPWRT` | NOT DONE | XXX - no stub added yet | -| `$BFB4` | `NEGOP` | NOT DONE | XXX - no stub added yet | +| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | +| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | +| `$BFB4` | `NEGOP` | NOT DONE | toggle FAC1 sign (if not 0) | | `$BFED` | `EXP` | NOT DONE | XXX - no stub added yet | -| `$E043` | `POLY1` | NOT DONE | XXX - no stub added yet | -| `$E059` | `POLY2` | NOT DONE | XXX - no stub added yet | -| `$E264` | `COS` | NOT DONE | XXX - no stub added yet | -| `$E26B` | `SIN` | NOT DONE | XXX - no stub added yet | -| `$E2B4` | `TAN` | NOT DONE | XXX - no stub added yet | +| `$E043` | `POLY1` | NOT DONE | evaluate polynomial with odd powers only | +| `$E059` | `POLY2` | NOT DONE | evaluate polynomial with odd and even powers | +| `$E264` | `COS` | NOT DONE | cosine of FAC1 in radians | +| `$E26B` | `SIN` | NOT DONE | sine of FAC1 in radians | +| `$E2B4` | `TAN` | NOT DONE | tangent of FAC1 in radians | | `$E30E` | `ATN` | NOT DONE | XXX - no stub added yet |
diff --git a/c64/basic/,stubs_math/b1aa.FACINX.s b/c64/basic/,stubs_math/b1aa.FACINX.s new file mode 100644 index 00000000..9769eeea --- /dev/null +++ b/c64/basic/,stubs_math/b1aa.FACINX.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - convert FAC1 to 16-bit signed integer +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 105 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +// XXX provide implementation + +FACINX: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b1aa.interop b/c64/basic/,stubs_math/b1aa.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b1aa.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b850.FSUB.s b/c64/basic/,stubs_math/b850.FSUB.s new file mode 100644 index 00000000..b5f3dc11 --- /dev/null +++ b/c64/basic/,stubs_math/b850.FSUB.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - subtract FAC1 from RAM +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FSUB: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b850.interop b/c64/basic/,stubs_math/b850.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b850.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b853.FSUBT.s b/c64/basic/,stubs_math/b853.FSUBT.s new file mode 100644 index 00000000..6e19e784 --- /dev/null +++ b/c64/basic/,stubs_math/b853.FSUBT.s @@ -0,0 +1,23 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - subtract FAC1 from FAC2 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FSUBT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b853.interop b/c64/basic/,stubs_math/b853.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b853.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b867.FADD.s b/c64/basic/,stubs_math/b867.FADD.s new file mode 100644 index 00000000..8187d247 --- /dev/null +++ b/c64/basic/,stubs_math/b867.FADD.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add RAM to FAC1 +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FADD: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b867.interop b/c64/basic/,stubs_math/b867.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b867.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b86a.FADDT.s b/c64/basic/,stubs_math/b86a.FADDT.s new file mode 100644 index 00000000..a1cf6d08 --- /dev/null +++ b/c64/basic/,stubs_math/b86a.FADDT.s @@ -0,0 +1,23 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add FAC2 to FAC1 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FADDT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b86a.interop b/c64/basic/,stubs_math/b86a.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b86a.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/ba28.FMUL.s b/c64/basic/,stubs_math/ba28.FMUL.s new file mode 100644 index 00000000..f79b830b --- /dev/null +++ b/c64/basic/,stubs_math/ba28.FMUL.s @@ -0,0 +1,24 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - multiplies FAC1 by RAM +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// Note: +// - C64 Wiki calls it FMULT, this looks like a mistake +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FMUL: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba28.interop b/c64/basic/,stubs_math/ba28.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/ba28.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/ba2b.FMULT.s b/c64/basic/,stubs_math/ba2b.FMULT.s new file mode 100644 index 00000000..1a3ef3ab --- /dev/null +++ b/c64/basic/,stubs_math/ba2b.FMULT.s @@ -0,0 +1,23 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - multiplies FAC1 by FAC2 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FMULT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba2b.interop b/c64/basic/,stubs_math/ba2b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/ba2b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bae2.MUL10.s b/c64/basic/,stubs_math/bae2.MUL10.s new file mode 100644 index 00000000..3fde16d3 --- /dev/null +++ b/c64/basic/,stubs_math/bae2.MUL10.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - multiply FAC1 by 10 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +MUL10: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bae2.interop b/c64/basic/,stubs_math/bae2.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bae2.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bafe.DIV10.s b/c64/basic/,stubs_math/bafe.DIV10.s new file mode 100644 index 00000000..3d59810d --- /dev/null +++ b/c64/basic/,stubs_math/bafe.DIV10.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - divide FAC1 by 10, result is always positive +// +// Notes: +// - shifts FAC1 to FAC2, loads FAC1 with the constant 10, falls through to the division routine + +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +DIV10: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bafe.interop b/c64/basic/,stubs_math/bafe.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bafe.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bb0f.FDIV.c b/c64/basic/,stubs_math/bb0f.FDIV.c new file mode 100644 index 00000000..386c63d5 --- /dev/null +++ b/c64/basic/,stubs_math/bb0f.FDIV.c @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - divide RAM by FAC1 +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FDIV: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bb0f.interop b/c64/basic/,stubs_math/bb0f.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bb0f.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bb12.FDIVT.s b/c64/basic/,stubs_math/bb12.FDIVT.s new file mode 100644 index 00000000..d02ef219 --- /dev/null +++ b/c64/basic/,stubs_math/bb12.FDIVT.s @@ -0,0 +1,23 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - divide FAC2 by FAC1, ignores sign +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Output: +// - leaves the quotient FAC1 and the remainder in FAC2 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FDIVT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bb12.interop b/c64/basic/,stubs_math/bb12.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bb12.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc2b.SIGN.s b/c64/basic/,stubs_math/bc2b.SIGN.s new file mode 100644 index 00000000..e0a98612 --- /dev/null +++ b/c64/basic/,stubs_math/bc2b.SIGN.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - evaluate FAC1 sign +// +// Output: +// - .A - $00 for equal, $01 for FAC1 > RAM, $FF for FAC1 < RAM +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +SIGN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc2b.interop b/c64/basic/,stubs_math/bc2b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc2b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc5b.FCOMP.s b/c64/basic/,stubs_math/bc5b.FCOMP.s new file mode 100644 index 00000000..c73858b7 --- /dev/null +++ b/c64/basic/,stubs_math/bc5b.FCOMP.s @@ -0,0 +1,28 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - compare FAC1 with RAM location +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// Output: +// - .A - $00 for equal, $01 for FAC1 > RAM, $FF for FAC1 < RAM +// - flags N/Z, depending on whether FAC1 is 0, positive, or negative +// +// Notes: +// - uses vector at $24, leaves FAC1 and FAC2 unchanged (Codebase64) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FCOMP: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc5b.interop b/c64/basic/,stubs_math/bc5b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc5b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bf78.FPWR.s b/c64/basic/,stubs_math/bf78.FPWR.s new file mode 100644 index 00000000..42226482 --- /dev/null +++ b/c64/basic/,stubs_math/bf78.FPWR.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - set FAC1 as RAM raised to the power of FAC1 +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 (FPWRT) +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FPWR: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf78.interop b/c64/basic/,stubs_math/bf78.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bf78.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bf7b.FPWRT.s b/c64/basic/,stubs_math/bf7b.FPWRT.s new file mode 100644 index 00000000..7dfbc8c9 --- /dev/null +++ b/c64/basic/,stubs_math/bf7b.FPWRT.s @@ -0,0 +1,24 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - set FAC1 as FAC2 raised to the power of FAC1 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// - uses exp(x*log(y)) formula to calculate y^x; slow and inaccurate +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FPWRT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf7b.interop b/c64/basic/,stubs_math/bf7b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bf7b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bfb4.NEGOP.s b/c64/basic/,stubs_math/bfb4.NEGOP.s new file mode 100644 index 00000000..838f92c5 --- /dev/null +++ b/c64/basic/,stubs_math/bfb4.NEGOP.s @@ -0,0 +1,16 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - toggle FAC1 sign (if not 0) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +// XXX provide implementation + +NEGOP: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bfb4.interop b/c64/basic/,stubs_math/bfb4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bfb4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e043.POLY1.s b/c64/basic/,stubs_math/e043.POLY1.s new file mode 100644 index 00000000..c4042bc8 --- /dev/null +++ b/c64/basic/,stubs_math/e043.POLY1.s @@ -0,0 +1,27 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - evaluate polynomial with odd powers only for FAC1 value +// +// Input: +// - .A - table address low byte +// - .Y - table address low byte +// - table format: +// - polynomial degree (8 bit integer) +// - oefficients (floats), starting from highest degree, times 1+degree +// +// Notes: +// - calls POLY2(table, X*X)*X +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 206 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://www.c64-wiki.com/wiki/POLY1 +// + +// XXX provide implementation + +POLY1: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e043.interop b/c64/basic/,stubs_math/e043.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e043.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e059.POLY2.s b/c64/basic/,stubs_math/e059.POLY2.s new file mode 100644 index 00000000..b2d94100 --- /dev/null +++ b/c64/basic/,stubs_math/e059.POLY2.s @@ -0,0 +1,27 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - evaluate polynomial with odd and even powers for FAC1 value +// +// Input: +// - .A - table address low byte +// - .Y - table address low byte +// - table format: +// - polynomial degree (8 bit integer) +// - oefficients (floats), starting from highest degree, times 1+degree +// +// Notes: +// - uses Horner method +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 207 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://www.c64-wiki.com/wiki/POLY1 +// + +// XXX provide implementation + +POLY2: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e059.interop b/c64/basic/,stubs_math/e059.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e059.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e264.COS.s b/c64/basic/,stubs_math/e264.COS.s new file mode 100644 index 00000000..bdf0b761 --- /dev/null +++ b/c64/basic/,stubs_math/e264.COS.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - cosine of FAC1 in radians +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 210 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +COS: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e264.interop b/c64/basic/,stubs_math/e264.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e264.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e26b.SIN.s b/c64/basic/,stubs_math/e26b.SIN.s new file mode 100644 index 00000000..5ca46126 --- /dev/null +++ b/c64/basic/,stubs_math/e26b.SIN.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - sine of FAC1 in radians +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 210 - XXX address does not match +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +SIN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e26b.interop b/c64/basic/,stubs_math/e26b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e26b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e2b4.TAN.s b/c64/basic/,stubs_math/e2b4.TAN.s new file mode 100644 index 00000000..d0cc416d --- /dev/null +++ b/c64/basic/,stubs_math/e2b4.TAN.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - tangent of FAC1 in radians +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 210 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +TAN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e2b4.interop b/c64/basic/,stubs_math/e2b4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e2b4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example From 2d1d7ee0b447b9aa5d565e3faf94a27dc5d5d150 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 19:18:59 +0100 Subject: [PATCH 20/66] implemented few trivial math routines --- Makefile | 1 + STATUS.md | 8 ++++---- c64/basic/{,stubs_math => math}/b850.FSUB.s | 7 ++++--- c64/basic/{,stubs_math => math}/b850.interop | 0 c64/basic/{,stubs_math => math}/b867.FADD.s | 7 ++++--- c64/basic/{,stubs_math => math}/b867.interop | 0 c64/basic/{,stubs_math => math}/ba28.FMUL.s | 7 ++++--- c64/basic/{,stubs_math => math}/ba28.interop | 0 c64/basic/{,stubs_math/bb0f.FDIV.c => math/bb0f.FDIV.s} | 7 ++++--- c64/basic/{,stubs_math => math}/bb0f.interop | 0 10 files changed, 21 insertions(+), 16 deletions(-) rename c64/basic/{,stubs_math => math}/b850.FSUB.s (89%) rename c64/basic/{,stubs_math => math}/b850.interop (100%) rename c64/basic/{,stubs_math => math}/b867.FADD.s (88%) rename c64/basic/{,stubs_math => math}/b867.interop (100%) rename c64/basic/{,stubs_math => math}/ba28.FMUL.s (90%) rename c64/basic/{,stubs_math => math}/ba28.interop (100%) rename c64/basic/{,stubs_math/bb0f.FDIV.c => math/bb0f.FDIV.s} (88%) rename c64/basic/{,stubs_math => math}/bb0f.interop (100%) diff --git a/Makefile b/Makefile index 84736f02..4b7a420f 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \ c64/basic/,stubs_math \ c64/basic/commands \ c64/basic/init \ + c64/basic/math \ c64/basic/rom_revision SRCDIR_KERNAL = $(SRCDIR_COMMON) \ diff --git a/STATUS.md b/STATUS.md index ec4a88fe..236285dc 100644 --- a/STATUS.md +++ b/STATUS.md @@ -179,17 +179,17 @@ Floating point mathematical routines - not official, but well known and broadly | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | | `$B391` | `GIVAYF` | NOT DONE | XXX - no stub added yet | | `$B7B5` | `STRVAL` | NOT DONE | XXX - no stub added yet | -| `$B850` | `FSUB` | NOT DONE | subtract FAC1 from RAM | +| `$B850` | `FSUB` | PARTIAL | needs `CONUPK` and `FSUBT` | | `$B853` | `FSUBT` | NOT DONE | subtract FAC1 from FAC2 | -| `$B867` | `FADD` | NOT DONE | add RAM to FAC1 | +| `$B867` | `FADD` | PARTIAL | needs `CONUPK` and `FADDT` | | `$B86A` | `FADDT` | NOT DONE | add FAC2 to FAC1 | | `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | -| `$BA28` | `FMUL` | NOT DONE | multiplies FAC1 by RAM | +| `$BA28` | `FMUL` | PARTIAL | needs `CONUPK` and `FMULT` | | `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | | `$BA8C` | `CONUPK` | NOT DONE | fetch FAC2 from RAM location | | `$BAE2` | `MUL10` | NOT DONE | multiply FAC1 by 10 | | `$BAFE` | `DIV10` | NOT DONE | divide FAC1 by 10, result is always positive | -| `$BB0F` | `FDIV` | NOT DONE | divide RAM by FAC1 | +| `$BB0F` | `FDIV` | PARTIAL | needs `CONUPK` and `FDIVT` | | `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | | `$BBA2` | `MOVFM` | NOT DONE | fetch FAC1 from RAM location | | `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | diff --git a/c64/basic/,stubs_math/b850.FSUB.s b/c64/basic/math/b850.FSUB.s similarity index 89% rename from c64/basic/,stubs_math/b850.FSUB.s rename to c64/basic/math/b850.FSUB.s index b5f3dc11..ca6d9488 100644 --- a/c64/basic/,stubs_math/b850.FSUB.s +++ b/c64/basic/math/b850.FSUB.s @@ -15,7 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation - FSUB: - STUB_IMPLEMENTATION() + + jsr CONUPK + + // FALLTROUGH to FSUBT diff --git a/c64/basic/,stubs_math/b850.interop b/c64/basic/math/b850.interop similarity index 100% rename from c64/basic/,stubs_math/b850.interop rename to c64/basic/math/b850.interop diff --git a/c64/basic/,stubs_math/b867.FADD.s b/c64/basic/math/b867.FADD.s similarity index 88% rename from c64/basic/,stubs_math/b867.FADD.s rename to c64/basic/math/b867.FADD.s index 8187d247..e5bd97b3 100644 --- a/c64/basic/,stubs_math/b867.FADD.s +++ b/c64/basic/math/b867.FADD.s @@ -15,7 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation - FADD: - STUB_IMPLEMENTATION() + + jsr CONUPK + + // FALLTROUGH to FADDT diff --git a/c64/basic/,stubs_math/b867.interop b/c64/basic/math/b867.interop similarity index 100% rename from c64/basic/,stubs_math/b867.interop rename to c64/basic/math/b867.interop diff --git a/c64/basic/,stubs_math/ba28.FMUL.s b/c64/basic/math/ba28.FMUL.s similarity index 90% rename from c64/basic/,stubs_math/ba28.FMUL.s rename to c64/basic/math/ba28.FMUL.s index f79b830b..3e02237a 100644 --- a/c64/basic/,stubs_math/ba28.FMUL.s +++ b/c64/basic/math/ba28.FMUL.s @@ -18,7 +18,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation - FMUL: - STUB_IMPLEMENTATION() + + jsr CONUPK + + // FALLTROUGH to FMULT diff --git a/c64/basic/,stubs_math/ba28.interop b/c64/basic/math/ba28.interop similarity index 100% rename from c64/basic/,stubs_math/ba28.interop rename to c64/basic/math/ba28.interop diff --git a/c64/basic/,stubs_math/bb0f.FDIV.c b/c64/basic/math/bb0f.FDIV.s similarity index 88% rename from c64/basic/,stubs_math/bb0f.FDIV.c rename to c64/basic/math/bb0f.FDIV.s index 386c63d5..cce82469 100644 --- a/c64/basic/,stubs_math/bb0f.FDIV.c +++ b/c64/basic/math/bb0f.FDIV.s @@ -15,7 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation - FDIV: - STUB_IMPLEMENTATION() + + jsr CONUPK + + // FALLTROUGH to FDIVT diff --git a/c64/basic/,stubs_math/bb0f.interop b/c64/basic/math/bb0f.interop similarity index 100% rename from c64/basic/,stubs_math/bb0f.interop rename to c64/basic/math/bb0f.interop From 733bf8d2baab57aaf7d9720e125d717931be6224 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 20:12:53 +0100 Subject: [PATCH 21/66] implemented CONUPK math routine --- STATUS.md | 10 +-- c64/basic/,stubs_math/ba8c.CONUPK.s | 64 ++++++++++++++- c64/basic/math/ba8c.CONUPK.s | 82 ++++++++++++++++++++ c64/basic/{,stubs_math => math}/ba8c.interop | 0 4 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 c64/basic/math/ba8c.CONUPK.s rename c64/basic/{,stubs_math => math}/ba8c.interop (100%) diff --git a/STATUS.md b/STATUS.md index 236285dc..f21b68a8 100644 --- a/STATUS.md +++ b/STATUS.md @@ -179,17 +179,17 @@ Floating point mathematical routines - not official, but well known and broadly | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | | `$B391` | `GIVAYF` | NOT DONE | XXX - no stub added yet | | `$B7B5` | `STRVAL` | NOT DONE | XXX - no stub added yet | -| `$B850` | `FSUB` | PARTIAL | needs `CONUPK` and `FSUBT` | +| `$B850` | `FSUB` | PARTIAL | needs `FSUBT` | | `$B853` | `FSUBT` | NOT DONE | subtract FAC1 from FAC2 | -| `$B867` | `FADD` | PARTIAL | needs `CONUPK` and `FADDT` | +| `$B867` | `FADD` | PARTIAL | needs `FADDT` | | `$B86A` | `FADDT` | NOT DONE | add FAC2 to FAC1 | | `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | -| `$BA28` | `FMUL` | PARTIAL | needs `CONUPK` and `FMULT` | +| `$BA28` | `FMUL` | PARTIAL | needs `FMULT` | | `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | -| `$BA8C` | `CONUPK` | NOT DONE | fetch FAC2 from RAM location | +| `$BA8C` | `CONUPK` | PARTIAL | not tested yet | | `$BAE2` | `MUL10` | NOT DONE | multiply FAC1 by 10 | | `$BAFE` | `DIV10` | NOT DONE | divide FAC1 by 10, result is always positive | -| `$BB0F` | `FDIV` | PARTIAL | needs `CONUPK` and `FDIVT` | +| `$BB0F` | `FDIV` | PARTIAL | needs `FDIVT` | | `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | | `$BBA2` | `MOVFM` | NOT DONE | fetch FAC1 from RAM location | | `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | diff --git a/c64/basic/,stubs_math/ba8c.CONUPK.s b/c64/basic/,stubs_math/ba8c.CONUPK.s index f31ee902..9b042643 100644 --- a/c64/basic/,stubs_math/ba8c.CONUPK.s +++ b/c64/basic/,stubs_math/ba8c.CONUPK.s @@ -10,7 +10,11 @@ // - .Y - address high byte // // Output: -// - .A - FAC1 exponent (XXX really FAC1?) +// - .A - FAC1 exponent (yes, really - Codebase64 is right) +// - .Y - 0 (tested with original ROMs) +// +// Preserves: +// - .X (tested with original ROMs) // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 114 @@ -18,7 +22,61 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation +// XXX test this CONUPK: - STUB_IMPLEMENTATION() + + // Noticed in the avilable materials: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic + // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 + // that at least some math routines use $22/$23 (INDEX+0 and INDEX+1) for pointer storage, + // confirmed that this routine is not an exception + + sty INDEX+1 + sta INDEX+0 + + // Now copy the data from RAM to FAC2, for the format description see: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 + + ldy #$04 + + // Copy the mantissa - reverse byte order + + ldy #$04 + lda (INDEX), y + sta FAC2_mantissa+3 + + dey + lda (INDEX), y + sta FAC2_mantissa+2 + + dey + lda (INDEX), y + sta FAC2_mantissa+1 + + dey + lda (INDEX), y + ora #$80 // clear the sign bit + sta FAC2_mantissa+0 + + // Copy the sign + + lda (INDEX), y + bpl !+ // assumption: non-negative numbers are more frequent + lda #$FF + skip_2_bytes_trash_nvz +!: + lda $00 + + sta FAC2_sign + + // Copy the exponent + + dey + lda (INDEX), y + sta FAC2_exponent + + // Return the FAC1 exponent + + lda FAC1_exponent + rts diff --git a/c64/basic/math/ba8c.CONUPK.s b/c64/basic/math/ba8c.CONUPK.s new file mode 100644 index 00000000..9583c4a9 --- /dev/null +++ b/c64/basic/math/ba8c.CONUPK.s @@ -0,0 +1,82 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - fetch FAC2 from RAM location +// +// Input: +// - .A - address low byte +// - .Y - address high byte +// +// Output: +// - .A - FAC1 exponent (yes, really - Codebase64 is right) +// - .Y - XXX 0? +// +// Preserves: +// - .X - (experimentation with original routine) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX test this + +CONUPK: + + // Not sure which temporary variables are used for storage by the original ROMs, + // but $22/$23 (INDEX+0 and INDEX+1) seem to be good candidates, at least some + // math routines use them as pointer storage, see: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic + // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 + + sty INDEX+1 + sta INDEX+0 + + // Now copy the data from RAM to FAC2, for the format description see: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 + + ldy #$04 + + // Copy the mantissa - reverse byte order + + ldy #$04 + lda (INDEX), y + sta FAC2_mantissa+3 + + dey + lda (INDEX), y + sta FAC2_mantissa+2 + + dey + lda (INDEX), y + sta FAC2_mantissa+1 + + dey + lda (INDEX), y + ora #$80 // clear the sign bit + sta FAC2_mantissa+0 + + // Copy the sign + + lda (INDEX), y + bpl !+ // assumption: non-negative numbers are more frequent + lda #$FF + skip_2_bytes_trash_nvz +!: + lda $00 + + sta FAC2_sign + + // Copy the exponent + + dey + lda (INDEX), y + sta FAC2_exponent + + // Return the FAC1 exponent + + lda FAC1_exponent + rts diff --git a/c64/basic/,stubs_math/ba8c.interop b/c64/basic/math/ba8c.interop similarity index 100% rename from c64/basic/,stubs_math/ba8c.interop rename to c64/basic/math/ba8c.interop From 0e319d987125c12baa3596b8b4ba193dd81cc088 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 20:28:01 +0100 Subject: [PATCH 22/66] implemented NEGOP math routine --- STATUS.md | 2 +- c64/aliases/,aliases_ram_lowmem.s | 2 +- c64/basic/{,stubs_math => math}/bfb4.NEGOP.s | 12 +++++++++--- c64/basic/{,stubs_math => math}/bfb4.interop | 0 4 files changed, 11 insertions(+), 5 deletions(-) rename c64/basic/{,stubs_math => math}/bfb4.NEGOP.s (66%) rename c64/basic/{,stubs_math => math}/bfb4.interop (100%) diff --git a/STATUS.md b/STATUS.md index f21b68a8..932b3690 100644 --- a/STATUS.md +++ b/STATUS.md @@ -206,7 +206,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BF71` | `SQR` | NOT DONE | XXX - no stub added yet | | `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | | `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | -| `$BFB4` | `NEGOP` | NOT DONE | toggle FAC1 sign (if not 0) | +| `$BFB4` | `NEGOP` | DONE | | | `$BFED` | `EXP` | NOT DONE | XXX - no stub added yet | | `$E043` | `POLY1` | NOT DONE | evaluate polynomial with odd powers only | | `$E059` | `POLY2` | NOT DONE | evaluate polynomial with odd and even powers | diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index efb85ef8..828aef45 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -31,7 +31,7 @@ .label TEMPPT = $16 // -- NOT IMPLEMENTED -- .label LASTPT = $17 // $17-$18 -- NOT IMPLEMENTED -- .label TEMPST = $19 // $19-$21 -- NOT IMPLEMENTED -- - .label INDEX = $22 // $22-$25 -- NOT IMPLEMENTED -- temporary variables + .label INDEX = $22 // $22-$25 temporary variables, [!] our usage might be different .label RESHO = $26 // $26-$2A -- NOT IMPLEMENTED -- .label TXTTAB = $2B // $2B-$2C start of BASIC code .label VARTAB = $2D // $2D-$2E end of BASIC code, start of variables diff --git a/c64/basic/,stubs_math/bfb4.NEGOP.s b/c64/basic/math/bfb4.NEGOP.s similarity index 66% rename from c64/basic/,stubs_math/bfb4.NEGOP.s rename to c64/basic/math/bfb4.NEGOP.s index 838f92c5..c231407b 100644 --- a/c64/basic/,stubs_math/bfb4.NEGOP.s +++ b/c64/basic/math/bfb4.NEGOP.s @@ -10,7 +10,13 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -// XXX provide implementation - NEGOP: - STUB_IMPLEMENTATION() + + lda FAC1_exponent + beq !+ // do not toggle the sign if value is 0 + + lda FAC1_sign + eor #$FF + sta FAC1_sign +!: + rts diff --git a/c64/basic/,stubs_math/bfb4.interop b/c64/basic/math/bfb4.interop similarity index 100% rename from c64/basic/,stubs_math/bfb4.interop rename to c64/basic/math/bfb4.interop From 35712baca7a944eea34ce6c0ff23d47df22dd013 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 21:12:01 +0100 Subject: [PATCH 23/66] implemented MOVFM math routine --- STATUS.md | 4 +- c64/basic/,stubs_math/b853.FSUBT.s | 2 +- c64/basic/,stubs_math/b86a.FADDT.s | 2 +- c64/basic/,stubs_math/ba2b.FMULT.s | 2 +- c64/basic/,stubs_math/bba2.MOVFM.s | 25 ----------- c64/basic/,stubs_math/bbd4.MOVMF.s | 9 ++-- c64/basic/,stubs_math/bf7b.FPWRT.s | 2 +- c64/basic/math/ba8c.CONUPK.s | 12 +++--- .../ba8c.CONUPK.s => math/bba2.MOVFM.s} | 41 ++++++++++--------- c64/basic/{,stubs_math => math}/bba2.interop | 0 10 files changed, 38 insertions(+), 61 deletions(-) delete mode 100644 c64/basic/,stubs_math/bba2.MOVFM.s rename c64/basic/{,stubs_math/ba8c.CONUPK.s => math/bba2.MOVFM.s} (57%) rename c64/basic/{,stubs_math => math}/bba2.interop (100%) diff --git a/STATUS.md b/STATUS.md index 932b3690..411aca8f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -186,12 +186,12 @@ Floating point mathematical routines - not official, but well known and broadly | `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | | `$BA28` | `FMUL` | PARTIAL | needs `FMULT` | | `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | -| `$BA8C` | `CONUPK` | PARTIAL | not tested yet | +| `$BA8C` | `CONUPK` | PARTIAL | not fully tested yet | | `$BAE2` | `MUL10` | NOT DONE | multiply FAC1 by 10 | | `$BAFE` | `DIV10` | NOT DONE | divide FAC1 by 10, result is always positive | | `$BB0F` | `FDIV` | PARTIAL | needs `FDIVT` | | `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | -| `$BBA2` | `MOVFM` | NOT DONE | fetch FAC1 from RAM location | +| `$BBA2` | `MOVFM` | PARTIAL | not fully tested yet | | `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | | `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | | `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | diff --git a/c64/basic/,stubs_math/b853.FSUBT.s b/c64/basic/,stubs_math/b853.FSUBT.s index 6e19e784..58b4a4db 100644 --- a/c64/basic/,stubs_math/b853.FSUBT.s +++ b/c64/basic/,stubs_math/b853.FSUBT.s @@ -9,7 +9,7 @@ // - .A - must load FAC1 exponent ($61) beforehand to set the zero flag // // Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 112 diff --git a/c64/basic/,stubs_math/b86a.FADDT.s b/c64/basic/,stubs_math/b86a.FADDT.s index a1cf6d08..c48274a3 100644 --- a/c64/basic/,stubs_math/b86a.FADDT.s +++ b/c64/basic/,stubs_math/b86a.FADDT.s @@ -9,7 +9,7 @@ // - .A - must load FAC1 exponent ($61) beforehand to set the zero flag // // Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 112 diff --git a/c64/basic/,stubs_math/ba2b.FMULT.s b/c64/basic/,stubs_math/ba2b.FMULT.s index 1a3ef3ab..0344f167 100644 --- a/c64/basic/,stubs_math/ba2b.FMULT.s +++ b/c64/basic/,stubs_math/ba2b.FMULT.s @@ -9,7 +9,7 @@ // - .A - must load FAC1 exponent ($61) beforehand to set the zero flag // // Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match diff --git a/c64/basic/,stubs_math/bba2.MOVFM.s b/c64/basic/,stubs_math/bba2.MOVFM.s deleted file mode 100644 index 8be43857..00000000 --- a/c64/basic/,stubs_math/bba2.MOVFM.s +++ /dev/null @@ -1,25 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - copy FAC1 to memory location, rounds if asked -// -// Input: -// - .X - address low byte -// - .Y - address high byte -// - $70 - if MSB is set performs rouding -// -// Output: -// - .A - FAC1 exponent -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 114 -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -MOVMF: - STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bbd4.MOVMF.s b/c64/basic/,stubs_math/bbd4.MOVMF.s index a144da44..4a7a3d60 100644 --- a/c64/basic/,stubs_math/bbd4.MOVMF.s +++ b/c64/basic/,stubs_math/bbd4.MOVMF.s @@ -3,17 +3,18 @@ // #LAYOUT# * * #IGNORE // -// Math package - fetch FAC1 from RAM location +// Math package - copy FAC1 to memory location, rounds if asked // // Input: -// - .A - address low byte +// - .X - address low byte // - .Y - address high byte +// - $70 - if MSB is set performs rouding // // Output: -// - .A - FAC1 exponent, affects status flags -// - .Y - always 0 +// - .A - FAC1 exponent // // See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // diff --git a/c64/basic/,stubs_math/bf7b.FPWRT.s b/c64/basic/,stubs_math/bf7b.FPWRT.s index 7dfbc8c9..5c58e9f1 100644 --- a/c64/basic/,stubs_math/bf7b.FPWRT.s +++ b/c64/basic/,stubs_math/bf7b.FPWRT.s @@ -9,7 +9,7 @@ // - .A - must load FAC1 exponent ($61) beforehand to set the zero flag // // Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) // - uses exp(x*log(y)) formula to calculate y^x; slow and inaccurate // // See also: diff --git a/c64/basic/math/ba8c.CONUPK.s b/c64/basic/math/ba8c.CONUPK.s index 9583c4a9..a6ad4722 100644 --- a/c64/basic/math/ba8c.CONUPK.s +++ b/c64/basic/math/ba8c.CONUPK.s @@ -11,10 +11,10 @@ // // Output: // - .A - FAC1 exponent (yes, really - Codebase64 is right) -// - .Y - XXX 0? +// - .Y - 0 (experimentation with original ROM) // // Preserves: -// - .X - (experimentation with original routine) +// - .X - (experimentation with original ROM) // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 114 @@ -26,11 +26,11 @@ CONUPK: - // Not sure which temporary variables are used for storage by the original ROMs, - // but $22/$23 (INDEX+0 and INDEX+1) seem to be good candidates, at least some - // math routines use them as pointer storage, see: + // Checked in the available documentation: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 + // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. + // Confirmed by experimenting with original ROM that this is the case here too. sty INDEX+1 sta INDEX+0 @@ -38,8 +38,6 @@ CONUPK: // Now copy the data from RAM to FAC2, for the format description see: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 - ldy #$04 - // Copy the mantissa - reverse byte order ldy #$04 diff --git a/c64/basic/,stubs_math/ba8c.CONUPK.s b/c64/basic/math/bba2.MOVFM.s similarity index 57% rename from c64/basic/,stubs_math/ba8c.CONUPK.s rename to c64/basic/math/bba2.MOVFM.s index 9b042643..f0dbb066 100644 --- a/c64/basic/,stubs_math/ba8c.CONUPK.s +++ b/c64/basic/math/bba2.MOVFM.s @@ -2,35 +2,32 @@ // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE -// -// Math package - fetch FAC2 from RAM location +// Math package - fetch FAC1 from RAM location // // Input: // - .A - address low byte // - .Y - address high byte // // Output: -// - .A - FAC1 exponent (yes, really - Codebase64 is right) -// - .Y - 0 (tested with original ROMs) +// - .A - FAC1 exponent, affects status flags +// - .Y - always 0 // // Preserves: -// - .X (tested with original ROMs) +// - .X - (experimentation with original ROM) // // See also: -// - [CM64] Computes Mapping the Commodore 64 - page 114 // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// // XXX test this -CONUPK: +MOVMF: - // Noticed in the avilable materials: + // Checked in the available documentation: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 - // that at least some math routines use $22/$23 (INDEX+0 and INDEX+1) for pointer storage, - // confirmed that this routine is not an exception + // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. + // Confirmed by experimenting with original ROM that this is the case here too. sty INDEX+1 sta INDEX+0 @@ -38,26 +35,24 @@ CONUPK: // Now copy the data from RAM to FAC2, for the format description see: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 - ldy #$04 - // Copy the mantissa - reverse byte order ldy #$04 lda (INDEX), y - sta FAC2_mantissa+3 + sta FAC1_mantissa+3 dey lda (INDEX), y - sta FAC2_mantissa+2 + sta FAC1_mantissa+2 dey lda (INDEX), y - sta FAC2_mantissa+1 + sta FAC1_mantissa+1 dey lda (INDEX), y ora #$80 // clear the sign bit - sta FAC2_mantissa+0 + sta FAC1_mantissa+0 // Copy the sign @@ -68,13 +63,21 @@ CONUPK: !: lda $00 - sta FAC2_sign + sta FAC1_sign // Copy the exponent dey lda (INDEX), y - sta FAC2_exponent + sta FAC1_exponent + + // Set low order mantissa - to my surprise original ROM seems to put 0 to FACOW - XXX why??? + // Since we do not know the original value (lost due to variable format having one byte shorter + // mantissa than FAC1), it is probably best to put some approximate value here; putting $80 + // would be risky in case rouding is performed later, $7F seems to be sane choice + + lda #$7F + sta FACOV // Return the FAC1 exponent diff --git a/c64/basic/,stubs_math/bba2.interop b/c64/basic/math/bba2.interop similarity index 100% rename from c64/basic/,stubs_math/bba2.interop rename to c64/basic/math/bba2.interop From 861e7eedb6f4560cc0c57d8e86a972ca207480b9 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 29 Jan 2020 21:31:11 +0100 Subject: [PATCH 24/66] preparation for the next math routines --- c64/basic/math/{ba8c.CONUPK.s => CONUPK.s} | 0 c64/basic/math/{bba2.MOVFM.s => MOVFM.s} | 0 c64/basic/math/b867.interop | 3 ++- c64/basic/math/ba8c.CONUPK.jmp.s | 7 +++++++ c64/basic/math/bba2.MOVFM.jmp.s | 7 +++++++ c64/basic/math/bba2.interop | 3 ++- 6 files changed, 18 insertions(+), 2 deletions(-) rename c64/basic/math/{ba8c.CONUPK.s => CONUPK.s} (100%) rename c64/basic/math/{bba2.MOVFM.s => MOVFM.s} (100%) create mode 100644 c64/basic/math/ba8c.CONUPK.jmp.s create mode 100644 c64/basic/math/bba2.MOVFM.jmp.s diff --git a/c64/basic/math/ba8c.CONUPK.s b/c64/basic/math/CONUPK.s similarity index 100% rename from c64/basic/math/ba8c.CONUPK.s rename to c64/basic/math/CONUPK.s diff --git a/c64/basic/math/bba2.MOVFM.s b/c64/basic/math/MOVFM.s similarity index 100% rename from c64/basic/math/bba2.MOVFM.s rename to c64/basic/math/MOVFM.s diff --git a/c64/basic/math/b867.interop b/c64/basic/math/b867.interop index 0d18777c..0975813a 100644 --- a/c64/basic/math/b867.interop +++ b/c64/basic/math/b867.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Routine probably used very often, it's call can be seen in a tutorial here: +- https://codebase64.org/doku.php?id=base:generating_sines_with_basic diff --git a/c64/basic/math/ba8c.CONUPK.jmp.s b/c64/basic/math/ba8c.CONUPK.jmp.s new file mode 100644 index 00000000..53809055 --- /dev/null +++ b/c64/basic/math/ba8c.CONUPK.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp CONUPK diff --git a/c64/basic/math/bba2.MOVFM.jmp.s b/c64/basic/math/bba2.MOVFM.jmp.s new file mode 100644 index 00000000..d62c457d --- /dev/null +++ b/c64/basic/math/bba2.MOVFM.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp MOVMF diff --git a/c64/basic/math/bba2.interop b/c64/basic/math/bba2.interop index 0d18777c..0975813a 100644 --- a/c64/basic/math/bba2.interop +++ b/c64/basic/math/bba2.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Routine probably used very often, it's call can be seen in a tutorial here: +- https://codebase64.org/doku.php?id=base:generating_sines_with_basic From 4de080cd90ccecd98866ae663db6935413c966d5 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 30 Jan 2020 16:51:15 +0100 Subject: [PATCH 25/66] added segment 1 for BASIC on Mega65 --- Makefile | 130 +++++++++++++++++++++----------------- c64/basic/banking/dummy.s | 7 ++ 2 files changed, 80 insertions(+), 57 deletions(-) create mode 100644 c64/basic/banking/dummy.s diff --git a/Makefile b/Makefile index 4b7a420f..d3f98316 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \ c64/basic \ c64/basic/,stubs \ c64/basic/,stubs_math \ + c64/basic/banking \ c64/basic/commands \ c64/basic/init \ c64/basic/math \ @@ -96,6 +97,11 @@ STD_TARGET_LIST = build/chargen.rom \ EXT_TARGET_LIST = build/mega65.rom +SEG_LIST_MEGA65 = $(DIR_MEGA65)/basic.seg_0 \ + $(DIR_MEGA65)/basic.seg_1 \ + $(DIR_MEGA65)/kernal.seg_0 \ + $(DIR_MEGA65)/kernal.seg_1 + REL_TARGET_LIST = $(pathsubst build/%,bin/%, $(STD_TARGET_LIST)) # Misc strings @@ -146,49 +152,53 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies - BASIC and KERNAL -$(DIR_CUSTOM)/OUTB.BIN $(DIR_CUSTOM)/BASIC_combined.vs: \ +$(DIR_CUSTOM)/OUTB_X.BIN $(DIR_CUSTOM)/BASIC_combined.vs: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_CUSTOM) $(DIR_CUSTOM)/KERNAL_combined.sym -$(DIR_GENERIC)/OUTB.BIN $(DIR_GENERIC)/BASIC_combined.vs: \ +$(DIR_GENERIC)/OUTB_X.BIN $(DIR_GENERIC)/BASIC_combined.vs: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_GENERIC) $(DIR_GENERIC)/KERNAL_combined.sym -$(DIR_TESTING)/OUTB.BIN $(DIR_TESTING)/BASIC_combined.vs: \ +$(DIR_TESTING)/OUTB_X.BIN $(DIR_TESTING)/BASIC_combined.vs: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_TESTING) $(DIR_TESTING)/KERNAL_combined.sym -$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym -$(DIR_ULTIMATE64)/OUTB.BIN $(DIR_ULTIMATE64)/BASIC_combined.vs: \ +$(DIR_ULTIMATE64)/OUTB_X.BIN $(DIR_ULTIMATE64)/BASIC_combined.vs: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_ULTIMATE64) $(DIR_ULTIMATE64)/KERNAL_combined.sym -$(DIR_CUSTOM)/OUTK.BIN $(DIR_CUSTOM)/KERNAL_combined.vs $(DIR_CUSTOM)/KERNAL_combined.sym: \ +$(DIR_CUSTOM)/OUTK_X.BIN $(DIR_CUSTOM)/KERNAL_combined.vs $(DIR_CUSTOM)/KERNAL_combined.sym: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_CUSTOM) -$(DIR_GENERIC)/OUTK.BIN $(DIR_GENERIC)/KERNAL_combined.vs $(DIR_GENERIC)/KERNAL_combined.sym: \ +$(DIR_GENERIC)/OUTK_X.BIN $(DIR_GENERIC)/KERNAL_combined.vs $(DIR_GENERIC)/KERNAL_combined.sym: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_GENERIC) -$(DIR_TESTING)/OUTK.BIN $(DIR_TESTING)KERNAL_combined.vs $(DIR_TESTING)/KERNAL_combined.sym: \ +$(DIR_TESTING)/OUTK_X.BIN $(DIR_TESTING)KERNAL_combined.vs $(DIR_TESTING)/KERNAL_combined.sym: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_TESTING) -$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) -$(DIR_ULTIMATE64)/OUTK.BIN $(DIR_ULTIMATE64)/KERNAL_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.sym: \ +$(DIR_ULTIMATE64)/OUTK_X.BIN $(DIR_ULTIMATE64)/KERNAL_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.sym: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_ULTIMATE64) + +$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/BASIC_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym +$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) + +$(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1_combined.vs $(DIR_MEGA65)/BASIC_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym $(DIR_MEGA65)/BASIC_0_combined.sym $(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: \ $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym -$(DIR_CUSTOM)/newrom: $(DIR_CUSTOM)/OUTB.BIN $(DIR_CUSTOM)/OUTK.BIN -$(DIR_GENERIC)/newrom: $(DIR_GENERIC)/OUTB.BIN $(DIR_GENERIC)/OUTK.BIN -$(DIR_TESTING)/newrom: $(DIR_TESTING)/OUTB.BIN $(DIR_TESTING)/OUTK.BIN -$(DIR_MEGA65)/newrom_0: $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN -$(DIR_ULTIMATE64)/newrom: $(DIR_ULTIMATE64)/OUTB.BIN $(DIR_ULTIMATE64)/OUTK.BIN +$(DIR_CUSTOM)/OUTX_X.BIN: $(DIR_CUSTOM)/OUTB_X.BIN $(DIR_CUSTOM)/OUTK_X.BIN +$(DIR_GENERIC)/OUTX_X.BIN: $(DIR_GENERIC)/OUTB_X.BIN $(DIR_GENERIC)/OUTK_X.BIN +$(DIR_TESTING)/OUTX_X.BIN: $(DIR_TESTING)/OUTB_X.BIN $(DIR_TESTING)/OUTK_X.BIN +$(DIR_MEGA65)/OUTX_0.BIN: $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN +$(DIR_ULTIMATE64)/OUTX_X.BIN: $(DIR_ULTIMATE64)/OUTB_X.BIN $(DIR_ULTIMATE64)/OUTK_X.BIN -build/kernal_custom.rom: $(DIR_CUSTOM)/newrom -build/kernal_generic.rom: $(DIR_GENERIC)/newrom -build/kernal_testing.rom: $(DIR_TESTING)/newrom -build/kernal_ultimate64.rom: $(DIR_ULTIMATE64)/newrom +build/kernal_custom.rom: $(DIR_CUSTOM)/OUTX_X.BIN +build/kernal_generic.rom: $(DIR_GENERIC)/OUTX_X.BIN +build/kernal_testing.rom: $(DIR_TESTING)/OUTX_X.BIN +build/kernal_ultimate64.rom: $(DIR_ULTIMATE64)/OUTX_X.BIN -build/basic_custom.rom: $(DIR_CUSTOM)/newrom -build/basic_generic.rom: $(DIR_GENERIC)/newrom -build/basic_testing.rom: $(DIR_TESTING)/newrom -build/basic_ultimate64.rom: $(DIR_ULTIMATE64)/newrom +build/basic_custom.rom: $(DIR_CUSTOM)/OUTX_X.BIN +build/basic_generic.rom: $(DIR_GENERIC)/OUTX_X.BIN +build/basic_testing.rom: $(DIR_TESTING)/OUTX_X.BIN +build/basic_ultimate64.rom: $(DIR_ULTIMATE64)/OUTX_X.BIN -$(DIR_MEGA65)/kernal.seg_0: $(DIR_MEGA65)/newrom_0 -$(DIR_MEGA65)/basic.seg_0: $(DIR_MEGA65)/newrom_0 +$(DIR_MEGA65)/kernal.seg_0: $(DIR_MEGA65)/OUTX_0.BIN +$(DIR_MEGA65)/basic.seg_0: $(DIR_MEGA65)/OUTX_0.BIN build/symbols_custom.vs: $(DIR_CUSTOM)/BASIC_combined.vs $(DIR_CUSTOM)/KERNAL_combined.vs build/symbols_generic.vs: $(DIR_GENERIC)/BASIC_combined.vs $(DIR_GENERIC)/KERNAL_combined.vs @@ -202,19 +212,19 @@ build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT) @mkdir -p build/,generated $(TOOL_COMPRESS_TEXT) > build/,generated/packed_messages.s -.PRECIOUS: build/target_%/OUTB.BIN build/target_%/BASIC_combined.vs -build/target_%/OUTB.BIN build/target_%/BASIC_combined.vs: +.PRECIOUS: build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs +build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs: @mkdir -p build/target_$* @rm -f $@* build/target_$*/BASIC* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s BASIC -i BASIC-$* -o OUTB.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC) $(GEN_BASIC) + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s BASIC -i BASIC-$* -o OUTB_X.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC) $(GEN_BASIC) -.PRECIOUS: build/target_%/OUTK.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym -build/target_%/OUTK.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym: +.PRECIOUS: build/target_%/OUTK_X.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym +build/target_%/OUTK_X.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym: @mkdir -p build/target_$* @rm -f $@* build/target_$*/KERNAL* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s KERNAL -i KERNAL-$* -o OUTK.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL) + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s KERNAL -i KERNAL-$* -o OUTK_X.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL) -$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs: +$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/BASIC_0_combined.sym: @mkdir -p $(DIR_MEGA65) @rm -f $@* $(DIR_MEGA65)/BASIC_0* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d $(DIR_MEGA65) -l a000 -h e4d2 $(CFG_MEGA65) $(SRCDIR_BASIC) $(GEN_BASIC) @@ -224,63 +234,69 @@ $(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL @rm -f $@* $(DIR_MEGA65)/KERNAL_0* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d $(DIR_MEGA65) -l e4d3 -h ffff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) +$(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1_combined.vs $(DIR_MEGA65)/BASIC_1_combined.sym: + @mkdir -p $(DIR_MEGA65) + @rm -f $@* $(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_MEGA65) -l 4000 -h 5fff $(CFG_MEGA65) $(SRCDIR_BASIC) $(GEN_BASIC) + $(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: @mkdir -p $(DIR_MEGA65) @rm -f $@* $(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1* @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d $(DIR_MEGA65) -l 4000 -h 5fff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) -.PRECIOUS: build/target_%/newrom -build/target_%/newrom: - cat build/target_$*/OUTB.BIN build/target_$*/OUTK.BIN > $@ +.PRECIOUS: build/target_%/OUTX_X.BIN +build/target_%/OUTX_X.BIN: + cat build/target_$*/OUTB_X.BIN build/target_$*/OUTK_X.BIN > $@ .PRECIOUS: build/kernal_%.rom build/kernal_%.rom: - dd if=build/target_$*/newrom bs=8192 count=1 skip=2 of=$@ + dd if=build/target_$*/OUTX_X.BIN bs=8192 count=1 skip=2 of=$@ .PRECIOUS: build/basic_%.rom build/basic_%.rom: - dd if=build/target_$*/newrom bs=8192 count=1 skip=0 of=$@ + dd if=build/target_$*/OUTX_X.BIN bs=8192 count=1 skip=0 of=$@ .PRECIOUS: build/symbols_%.vs build/symbols_%.vs: sort build/target_$*/BASIC_combined.vs build/target_$*/KERNAL_combined.vs | uniq | grep -v "__" > $@ -$(DIR_MEGA65)/newrom_0: +$(DIR_MEGA65)/OUTX_0.BIN: cat $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN > $@ $(DIR_MEGA65)/kernal.seg_0: - dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=2 of=$@ + dd if=$(DIR_MEGA65)/OUTX_0.BIN bs=8192 count=1 skip=2 of=$@ $(DIR_MEGA65)/basic.seg_0: - dd if=$(DIR_MEGA65)/newrom_0 bs=8192 count=1 skip=0 of=$@ + dd if=$(DIR_MEGA65)/OUTX_0.BIN bs=8192 count=1 skip=0 of=$@ -build/kernal_hybrid.rom: kernal $(DIR_GENERIC)/OUTK.BIN +build/kernal_hybrid.rom: kernal $(DIR_GENERIC)/OUTK_X.BIN @echo @echo $(HYBRID_WARNING) @echo (dd if=kernal bs=1140 count=1 skip=0 ; \ echo " > HYBRID ROM, DON'T DISTRIBUTE <" ; \ dd if=kernal bs=1 count=58 skip=1176 ; \ - cat $(DIR_GENERIC)/OUTK.BIN) > $@ + cat $(DIR_GENERIC)/OUTK_X.BIN) > $@ build/symbols_hybrid.vs: $(DIR_GENERIC)/KERNAL_combined.vs sort $(DIR_GENERIC)/KERNAL_combined.vs | uniq | grep -v "__" > $@ # Rules - platform 'Mega 65' specific -build/mega65.rom: $(DIR_MEGA65)/basic.seg_0 $(DIR_MEGA65)/kernal.seg_0 $(DIR_MEGA65)/kernal.seg_1 build/chargen.rom - dd if=/dev/zero bs=8192 count=1 of=build/padding_8k - dd if=/dev/zero bs=8192 count=8 of=build/padding_64k - cat build/padding_8k > build/mega65.rom - cat build/padding_8k >> build/mega65.rom +build/mega65.rom: $(SEG_LIST_MEGA65) build/chargen.rom + dd if=/dev/zero bs=8192 count=1 of=build/padding___08_KB + dd if=/dev/zero bs=8192 count=8 of=build/padding___64_KB + cat build/padding___08_KB > build/mega65.rom + cat build/padding___08_KB >> build/mega65.rom cat $(DIR_MEGA65)/kernal.seg_1 >> build/mega65.rom - cat build/padding_8k >> build/mega65.rom - cat build/padding_8k >> build/mega65.rom + cat $(DIR_MEGA65)/basic.seg_1 >> build/mega65.rom + cat build/padding___08_KB >> build/mega65.rom cat $(DIR_MEGA65)/basic.seg_0 >> build/mega65.rom - cat build/chargen.rom build/chargen.rom >> build/mega65.rom + cat build/chargen.rom >> build/mega65.rom + cat build/chargen.rom >> build/mega65.rom cat $(DIR_MEGA65)/kernal.seg_0 >> build/mega65.rom - cat build/padding_64k >> build/mega65.rom - rm -f build/padding* + cat build/padding___64_KB >> build/mega65.rom + rm -f build/padding___* # Rules - tests @@ -324,6 +340,6 @@ test_m65: build/mega65.rom testremote: build/kernal_custom.rom build/basic_custom.rom build/symbols_custom.vs x64 -kernal build/kernal_custom.rom -basic build/basic_custom.rom -moncommands build/symbols_custom.vs -remotemonitor -testsimilarity: $(TOOL_SIMILARITY) $(DIR_GENERIC)/newrom kernal basic - $(TOOL_SIMILARITY) kernal $(DIR_GENERIC)/newrom - $(TOOL_SIMILARITY) basic $(DIR_GENERIC)/newrom +testsimilarity: $(TOOL_SIMILARITY) $(DIR_GENERIC)/OUTX_X.BIN kernal basic + $(TOOL_SIMILARITY) kernal $(DIR_GENERIC)/OUTX_X.BIN + $(TOOL_SIMILARITY) basic $(DIR_GENERIC)/OUTX_X.BIN diff --git a/c64/basic/banking/dummy.s b/c64/basic/banking/dummy.s new file mode 100644 index 00000000..eea566c2 --- /dev/null +++ b/c64/basic/banking/dummy.s @@ -0,0 +1,7 @@ +// #LAYOUT# M65 BASIC_1 #TAKE +// #LAYOUT# * * #IGNORE + + +// Dummy, just to have anyything in segment 1 + + brk From 1b300aa39bff9c147c4246764e2e9815d0d94cfa Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 30 Jan 2020 21:26:01 +0100 Subject: [PATCH 26/66] implemented NORMAL math routine, added more stubs --- STATUS.md | 26 ++++---- c64/basic/,stubs_math/b391.GIVAYF.s | 20 ++++++ c64/basic/,stubs_math/b391.interop | 3 + c64/basic/,stubs_math/b7b5.STRVAL.s | 19 ++++++ c64/basic/,stubs_math/b7b5.interop | 3 + c64/basic/,stubs_math/b9ea.LOG.s | 18 +++++ c64/basic/,stubs_math/b9ea.interop | 3 + c64/basic/,stubs_math/bc2b.SIGN.s | 4 +- c64/basic/,stubs_math/bc39.SGN.s | 20 ++++++ c64/basic/,stubs_math/bc39.interop | 3 + c64/basic/,stubs_math/bc58.ABS.s | 17 +++++ c64/basic/,stubs_math/bc58.interop | 3 + c64/basic/,stubs_math/bc9b.QINT.s | 19 ++++++ c64/basic/,stubs_math/bc9b.interop | 3 + c64/basic/,stubs_math/bccc.INT.s | 17 +++++ c64/basic/,stubs_math/bccc.interop | 3 + c64/basic/,stubs_math/bcf3.FIN.s | 23 +++++++ c64/basic/,stubs_math/bcf3.interop | 3 + c64/basic/,stubs_math/bddd.FOUT.s | 21 ++++++ c64/basic/,stubs_math/bddd.interop | 3 + c64/basic/,stubs_math/bf71.SQR.s | 20 ++++++ c64/basic/,stubs_math/bf71.interop | 3 + c64/basic/,stubs_math/bf74.SQR2.s | 20 ++++++ c64/basic/,stubs_math/bf74.interop | 3 + c64/basic/,stubs_math/bfed.EXP.s | 18 +++++ c64/basic/,stubs_math/bfed.interop | 3 + c64/basic/,stubs_math/e30e.ATN.s | 17 +++++ c64/basic/,stubs_math/e30e.interop | 3 + c64/basic/math/NORMAL.s | 100 ++++++++++++++++++++++++++++ c64/basic/math/b8fe.NORMAL.jmp.s | 7 ++ c64/basic/math/b8fe.interop | 3 + 31 files changed, 414 insertions(+), 14 deletions(-) create mode 100644 c64/basic/,stubs_math/b391.GIVAYF.s create mode 100644 c64/basic/,stubs_math/b391.interop create mode 100644 c64/basic/,stubs_math/b7b5.STRVAL.s create mode 100644 c64/basic/,stubs_math/b7b5.interop create mode 100644 c64/basic/,stubs_math/b9ea.LOG.s create mode 100644 c64/basic/,stubs_math/b9ea.interop create mode 100644 c64/basic/,stubs_math/bc39.SGN.s create mode 100644 c64/basic/,stubs_math/bc39.interop create mode 100644 c64/basic/,stubs_math/bc58.ABS.s create mode 100644 c64/basic/,stubs_math/bc58.interop create mode 100644 c64/basic/,stubs_math/bc9b.QINT.s create mode 100644 c64/basic/,stubs_math/bc9b.interop create mode 100644 c64/basic/,stubs_math/bccc.INT.s create mode 100644 c64/basic/,stubs_math/bccc.interop create mode 100644 c64/basic/,stubs_math/bcf3.FIN.s create mode 100644 c64/basic/,stubs_math/bcf3.interop create mode 100644 c64/basic/,stubs_math/bddd.FOUT.s create mode 100644 c64/basic/,stubs_math/bddd.interop create mode 100644 c64/basic/,stubs_math/bf71.SQR.s create mode 100644 c64/basic/,stubs_math/bf71.interop create mode 100644 c64/basic/,stubs_math/bf74.SQR2.s create mode 100644 c64/basic/,stubs_math/bf74.interop create mode 100644 c64/basic/,stubs_math/bfed.EXP.s create mode 100644 c64/basic/,stubs_math/bfed.interop create mode 100644 c64/basic/,stubs_math/e30e.ATN.s create mode 100644 c64/basic/,stubs_math/e30e.interop create mode 100644 c64/basic/math/NORMAL.s create mode 100644 c64/basic/math/b8fe.NORMAL.jmp.s create mode 100644 c64/basic/math/b8fe.interop diff --git a/STATUS.md b/STATUS.md index 411aca8f..8d4e76d4 100644 --- a/STATUS.md +++ b/STATUS.md @@ -177,13 +177,14 @@ Floating point mathematical routines - not official, but well known and broadly | Address | Name | Status | Remarks | | :-------: | :----------- | :------: | :------------------------------------------------: | | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | -| `$B391` | `GIVAYF` | NOT DONE | XXX - no stub added yet | -| `$B7B5` | `STRVAL` | NOT DONE | XXX - no stub added yet | +| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | +| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | | `$B850` | `FSUB` | PARTIAL | needs `FSUBT` | | `$B853` | `FSUBT` | NOT DONE | subtract FAC1 from FAC2 | | `$B867` | `FADD` | PARTIAL | needs `FADDT` | | `$B86A` | `FADDT` | NOT DONE | add FAC2 to FAC1 | -| `$B9EA` | `LOG` | NOT DONE | XXX - no stub added yet | +| `$B8FE` | `NORMAL` | PARTIAL | not tested yet | +| `$B9EA` | `LOG` | NOT DONE | natural logarigthm | | `$BA28` | `FMUL` | PARTIAL | needs `FMULT` | | `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | | `$BA8C` | `CONUPK` | PARTIAL | not fully tested yet | @@ -196,24 +197,25 @@ Floating point mathematical routines - not official, but well known and broadly | `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | | `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | | `$BC2B` | `SIGN` | NOT DONE | evaluate FAC1 sign | -| `$BC39` | `SGN` | NOT DONE | XXX - no stub added yet | -| `$BC58` | `ABS` | NOT DONE | XXX - no stub added yet | +| `$BC39` | `SGN` | NOT DONE | evaluate FAC1 sign, to FAC1 | +| `$BC58` | `ABS` | NOT DONE | absolute value | | `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | -| `$BC9B` | `QINT` | NOT DONE | XXX - no stub added yet | -| `$BCCC` | `INT` | NOT DONE | XXX - no stub added yet | -| `$BCF3` | `FIN` | NOT DONE | XXX - no stub added yet | -| `$BDDD` | `FOUT` | NOT DONE | XXX - no stub added yet | -| `$BF71` | `SQR` | NOT DONE | XXX - no stub added yet | +| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | +| `$BCCC` | `INT` | NOT DONE | rounds away the decimal to make an integer | +| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | +| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | +| `$BF71` | `SQR` | NOT DONE | square root of FAC1 | +| `$BF74` | `SQR2` | NOT DONE | square root of FAC2 | | `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | | `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | | `$BFB4` | `NEGOP` | DONE | | -| `$BFED` | `EXP` | NOT DONE | XXX - no stub added yet | +| `$BFED` | `EXP` | NOT DONE | exponential function, e raised to FAC1 power | | `$E043` | `POLY1` | NOT DONE | evaluate polynomial with odd powers only | | `$E059` | `POLY2` | NOT DONE | evaluate polynomial with odd and even powers | | `$E264` | `COS` | NOT DONE | cosine of FAC1 in radians | | `$E26B` | `SIN` | NOT DONE | sine of FAC1 in radians | | `$E2B4` | `TAN` | NOT DONE | tangent of FAC1 in radians | -| `$E30E` | `ATN` | NOT DONE | XXX - no stub added yet | +| `$E30E` | `ATN` | NOT DONE | arc tangent of FAC1 |
diff --git a/c64/basic/,stubs_math/b391.GIVAYF.s b/c64/basic/,stubs_math/b391.GIVAYF.s new file mode 100644 index 00000000..44650977 --- /dev/null +++ b/c64/basic/,stubs_math/b391.GIVAYF.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - 16-bit signed integer to FAC1 +// +// Output: +// - .A - address high byte (XXX really, not the opposite?) +// - .Y - address low byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 107 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +// XXX provide implementation + +GIVAYF: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b391.interop b/c64/basic/,stubs_math/b391.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b391.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b7b5.STRVAL.s b/c64/basic/,stubs_math/b7b5.STRVAL.s new file mode 100644 index 00000000..35ae53d4 --- /dev/null +++ b/c64/basic/,stubs_math/b7b5.STRVAL.s @@ -0,0 +1,19 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - imports string to FAC1 - XXX: what about spaces? +// +// Input: +// - .A needs to be loaded with string length +// - string address in $22/$23 +// +// See also: +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +// XXX provide implementation + +STRVAL: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b7b5.interop b/c64/basic/,stubs_math/b7b5.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b7b5.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b9ea.LOG.s b/c64/basic/,stubs_math/b9ea.LOG.s new file mode 100644 index 00000000..3fc121a7 --- /dev/null +++ b/c64/basic/,stubs_math/b9ea.LOG.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - natural logarigthm +// +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +LOG: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b9ea.interop b/c64/basic/,stubs_math/b9ea.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b9ea.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc2b.SIGN.s b/c64/basic/,stubs_math/bc2b.SIGN.s index e0a98612..151b25d5 100644 --- a/c64/basic/,stubs_math/bc2b.SIGN.s +++ b/c64/basic/,stubs_math/bc2b.SIGN.s @@ -3,10 +3,10 @@ // #LAYOUT# * * #IGNORE // -// Math package - evaluate FAC1 sign +// Math package - evaluate FAC1 sign, to .A // // Output: -// - .A - $00 for equal, $01 for FAC1 > RAM, $FF for FAC1 < RAM +// - .A - 0 for FAC1 equal 0, 1 for FAC1 > 0, -1 for FAC1 < 0 // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 115 diff --git a/c64/basic/,stubs_math/bc39.SGN.s b/c64/basic/,stubs_math/bc39.SGN.s new file mode 100644 index 00000000..1b53f34c --- /dev/null +++ b/c64/basic/,stubs_math/bc39.SGN.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - evaluate FAC1 sign, to FAC1 +// +// Output: +// - FAC1 - 0 for FAC1 equal 0, 1 for FAC1 > 0, -1 for FAC1 < 0 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +SGN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc39.interop b/c64/basic/,stubs_math/bc39.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc39.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc58.ABS.s b/c64/basic/,stubs_math/bc58.ABS.s new file mode 100644 index 00000000..a152eb7e --- /dev/null +++ b/c64/basic/,stubs_math/bc58.ABS.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - absolute value +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +ABS: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc58.interop b/c64/basic/,stubs_math/bc58.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc58.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc9b.QINT.s b/c64/basic/,stubs_math/bc9b.QINT.s new file mode 100644 index 00000000..8414d0bd --- /dev/null +++ b/c64/basic/,stubs_math/bc9b.QINT.s @@ -0,0 +1,19 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - convert FAC1 to 32 bit signed integer +// +// Output: +// - $62-$65, big-endian order +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +// XXX provide implementation + +QINT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc9b.interop b/c64/basic/,stubs_math/bc9b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc9b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bccc.INT.s b/c64/basic/,stubs_math/bccc.INT.s new file mode 100644 index 00000000..a693a85d --- /dev/null +++ b/c64/basic/,stubs_math/bccc.INT.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - rounds away the decimal to make an integer +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 116 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +INT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bccc.interop b/c64/basic/,stubs_math/bccc.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bccc.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bcf3.FIN.s b/c64/basic/,stubs_math/bcf3.FIN.s new file mode 100644 index 00000000..2b85c855 --- /dev/null +++ b/c64/basic/,stubs_math/bcf3.FIN.s @@ -0,0 +1,23 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - imports string to FAC1, ignores spaces +// +// +// Input: +// - .A needs to be loaded with first char of the string +// - Carry flag must be clear +// - string address in $7A/$7B +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 116 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FIN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bcf3.interop b/c64/basic/,stubs_math/bcf3.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bcf3.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bddd.FOUT.s b/c64/basic/,stubs_math/bddd.FOUT.s new file mode 100644 index 00000000..c0597d05 --- /dev/null +++ b/c64/basic/,stubs_math/bddd.FOUT.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - outputs FAC1 to string at $0100 +// +// Output: +// - .A - address low byte +// - .Y - address high byte +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 116 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +FOUT: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bddd.interop b/c64/basic/,stubs_math/bddd.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bddd.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bf71.SQR.s b/c64/basic/,stubs_math/bf71.SQR.s new file mode 100644 index 00000000..4e1a3115 --- /dev/null +++ b/c64/basic/,stubs_math/bf71.SQR.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - square root of FAC1 +// +// Note: +// - transfers FAC1 to FAC2 and falls through to SQR2 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +SQR: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf71.interop b/c64/basic/,stubs_math/bf71.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bf71.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bf74.SQR2.s b/c64/basic/,stubs_math/bf74.SQR2.s new file mode 100644 index 00000000..abf1fc2d --- /dev/null +++ b/c64/basic/,stubs_math/bf74.SQR2.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - square root of FAC2 +// +// Note: +// - loads .5 into FAC1 and falling through to the exponentiation routine +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +SQR2: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf74.interop b/c64/basic/,stubs_math/bf74.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bf74.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bfed.EXP.s b/c64/basic/,stubs_math/bfed.EXP.s new file mode 100644 index 00000000..7ad24634 --- /dev/null +++ b/c64/basic/,stubs_math/bfed.EXP.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - exponential function, e raised to FAC1 power +// +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 117 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +EXP: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bfed.interop b/c64/basic/,stubs_math/bfed.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bfed.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/e30e.ATN.s b/c64/basic/,stubs_math/e30e.ATN.s new file mode 100644 index 00000000..642cea97 --- /dev/null +++ b/c64/basic/,stubs_math/e30e.ATN.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - arc tangent of FAC1 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 211 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +ATN: + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e30e.interop b/c64/basic/,stubs_math/e30e.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/e30e.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/NORMAL.s b/c64/basic/math/NORMAL.s new file mode 100644 index 00000000..f1e8fb61 --- /dev/null +++ b/c64/basic/math/NORMAL.s @@ -0,0 +1,100 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - normalize FAC1 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX test this + +NORMAL: + + lda FAC1_exponent + beq normal_end // branch if our float is 0 + + lda FAC1_mantissa+3 + beq normal_by_byte // branch if we can move the whole byte + + and #$80 + bne normal_end // branch if already normalized + + // FALLTROUGH + +normal_by_bit: + + // First check the current exponent + + lda FAC1_exponent + cmp #$01 + bne !+ + + // Exponent is 1 - just mark the whole number as 0 and finish + + lda #$00 + sta FAC1_exponent + rts +!: + // Multiply the mantissa by 2 + + clc + rol FACOV + rol FAC1_mantissa+0 + rol FAC1_mantissa+1 + rol FAC1_mantissa+2 + rol FAC1_mantissa+3 + + bcc NORMAL // branch if next iteration needed + rts + +normal_by_byte: + + // First decrement the exponent by 8, but not below 0 + + lda FAC1_exponent + sec + sbc #$08 + bcs !+ + lda #$00 +!: + sta FAC1_exponent + beq normal_end // branch if our float reached 0 + + // Now multiply the mantissa by 8 by moving the whole bytes + + lda FAC1_mantissa+2 + sta FAC1_mantissa+3 + lda FAC1_mantissa+1 + sta FAC1_mantissa+2 + lda FAC1_mantissa+0 + sta FAC1_mantissa+1 + + lda FACOV + sta FAC1_mantissa+0 + + lda #$00 + sta FACOV + + // Now check if mantissa is not 0 + + ora FAC1_mantissa+0 + ora FAC1_mantissa+1 + ora FAC1_mantissa+2 + ora FAC1_mantissa+3 + + bne NORMAL // not 0 - branch to next iteration + + // Our mantissa reached 0 - mark exponent as 0 and finish + + sta FAC1_exponent + + // FALLTROUGH + +normal_end: + + rts diff --git a/c64/basic/math/b8fe.NORMAL.jmp.s b/c64/basic/math/b8fe.NORMAL.jmp.s new file mode 100644 index 00000000..7c5c26b8 --- /dev/null +++ b/c64/basic/math/b8fe.NORMAL.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp NORMAL diff --git a/c64/basic/math/b8fe.interop b/c64/basic/math/b8fe.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/b8fe.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example From 64face2b030401268b8234c78c9e1e33a367bc62 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 30 Jan 2020 22:25:26 +0100 Subject: [PATCH 27/66] float transfer fix, some documentation updates --- c64/aliases/,aliases_cpu.s | 15 +++++++++++++++ c64/basic/math/MOVFM.s | 9 +++------ doc/Development.md | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/c64/aliases/,aliases_cpu.s b/c64/aliases/,aliases_cpu.s index 85f94c76..922a91bc 100644 --- a/c64/aliases/,aliases_cpu.s +++ b/c64/aliases/,aliases_cpu.s @@ -111,6 +111,21 @@ +// +// Calculation shortcuts +// + +.pseudocommand lda_zero // WARNING: do not use within interrupts +{ +#if HAS_OPCODES_65C02 + tba +#else + lda #$00 +#endif +} + + + // // Stack manipulation - some CPUs will leave .A unchanged, some will use it as temporary storage, so consider .A trashed // diff --git a/c64/basic/math/MOVFM.s b/c64/basic/math/MOVFM.s index f0dbb066..9f6c510c 100644 --- a/c64/basic/math/MOVFM.s +++ b/c64/basic/math/MOVFM.s @@ -71,13 +71,10 @@ MOVMF: lda (INDEX), y sta FAC1_exponent - // Set low order mantissa - to my surprise original ROM seems to put 0 to FACOW - XXX why??? - // Since we do not know the original value (lost due to variable format having one byte shorter - // mantissa than FAC1), it is probably best to put some approximate value here; putting $80 - // would be risky in case rouding is performed later, $7F seems to be sane choice + // Set low order mantissa to 0 - this should give the + // most precision while operating on integers - lda #$7F - sta FACOV + sty FACOV // Return the FAC1 exponent diff --git a/doc/Development.md b/doc/Development.md index 427a037b..86c3160d 100644 --- a/doc/Development.md +++ b/doc/Development.md @@ -88,7 +88,7 @@ List of the most important make targets: Currently there are 2 ROM layouts defined: - `STD` - with 2 code segments: `BASIC` (`$A000-$E4D2`, where `$C000-$DFFF` is a skip-gap for RAM and I/O area) and `KERNAL` (`$E4D3 - $FFFF`) -- `M65` - where `BASIC` becames `BASIC_0` and `KERNAL` becames `KERNAL_0`, additional segments might be added to the build system in the future; at the moment of writing this document additional 8KB of ROM is defined as `KERNAL_1` segment +- `M65` - where `BASIC` becames `BASIC_0` and `KERNAL` becames `KERNAL_0`, additional segments might be added to the build system in the future; at the moment of writing this document additional 8KB of ROM is defined as `BASIC_1` segment and additional 8KB of ROM is defined as `KERNAL_1` segment To check for current ROM layout or code segment use KickAssembler preprocessor defines, like `ROM_LAYOUT_STD`, `ROM_LAYOUT_M65`, `SEGMENT_BASIC`, `SEGMENT_KERNAL_1`. From f104746ebc76355f49aab97f01509eb8968b6241 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 30 Jan 2020 22:37:42 +0100 Subject: [PATCH 28/66] small tape code optimization --- c64/kernal/banking/mega65_imports.s | 7 ------- c64/kernal/tape/load_tape_turbo.s | 4 ---- .../tape/tape_turbo_byte_store_mega65.s | 19 ------------------- c64/kernal/tape/tape_turbo_bytestore.s | 17 ++++++++++++++++- 4 files changed, 16 insertions(+), 31 deletions(-) delete mode 100644 c64/kernal/tape/tape_turbo_byte_store_mega65.s diff --git a/c64/kernal/banking/mega65_imports.s b/c64/kernal/banking/mega65_imports.s index 8546e2ce..d06b0bdb 100644 --- a/c64/kernal/banking/mega65_imports.s +++ b/c64/kernal/banking/mega65_imports.s @@ -55,10 +55,3 @@ .label tape_normal_byte_store = KERNAL_0.tape_normal_byte_store #endif - - -#if CONFIG_TAPE_TURBO - -.label tape_turbo_byte_store = KERNAL_0.tape_turbo_byte_store - -#endif diff --git a/c64/kernal/tape/load_tape_turbo.s b/c64/kernal/tape/load_tape_turbo.s index ab42535d..7c421e90 100644 --- a/c64/kernal/tape/load_tape_turbo.s +++ b/c64/kernal/tape/load_tape_turbo.s @@ -128,11 +128,7 @@ load_tape_turbo_payload: load_tape_turbo_loop: jsr tape_turbo_get_byte -#if ROM_LAYOUT_M65 - jsr tape_turbo_byte_store -#else jsr __tape_turbo_bytestore // like 'sta (MEMUSS),y' - but under I/O -#endif eor PRTY // handle checksum sta PRTY diff --git a/c64/kernal/tape/tape_turbo_byte_store_mega65.s b/c64/kernal/tape/tape_turbo_byte_store_mega65.s deleted file mode 100644 index bfc4b77c..00000000 --- a/c64/kernal/tape/tape_turbo_byte_store_mega65.s +++ /dev/null @@ -1,19 +0,0 @@ -// #LAYOUT# M65 KERNAL_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Tape (turbo) helper routine - byte storage when ban changing is needed -// - - -#if CONFIG_TAPE_TURBO - - -tape_turbo_byte_store: - - jsr map_NORMAL - jsr __tape_turbo_bytestore // like 'sta (MEMUSS),y' - but under I/O - jmp map_KERNAL_1 - - -#endif diff --git a/c64/kernal/tape/tape_turbo_bytestore.s b/c64/kernal/tape/tape_turbo_bytestore.s index 25bf7a6b..03bd41f6 100644 --- a/c64/kernal/tape/tape_turbo_bytestore.s +++ b/c64/kernal/tape/tape_turbo_bytestore.s @@ -5,8 +5,10 @@ // // Tape (turbo) helper routine - storing byte uder I/O // +// Has to preserve .A and .Y +// -// This helper routine is meant to be copiet to the start of CPU stack. +// This helper routine is meant to be copied to the start of CPU stack. // Original ROM tape loading routines uses this area to store information // about bytes that did not read properly for the first time // (see Mapping the C64, page 47); this mechanism is useless for turbo tape, @@ -16,12 +18,20 @@ #if CONFIG_TAPE_TURBO +#if ROM_LAYOUT_M65 +.label __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 10 +#else .label __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 7 +#endif .label __tape_turbo_bytestore_size = __tape_turbo_bytestore_source_end - tape_turbo_bytestore_source tape_turbo_bytestore_source: +#if ROM_LAYOUT_M65 + jsr KERNAL_0.map_NORMAL +#endif + // Set all memory as RAM, tape motor ON ldx #$00 stx CPU_R6510 @@ -33,8 +43,13 @@ tape_turbo_bytestore_source: ldx #$00 // value will be determined later, offset from start: 7 bytes stx CPU_R6510 +#if ROM_LAYOUT_M65 + // Restore default map and quit + jmp KERNAL_0.map_KERNAL_1 +#else // Go back rts +#endif __tape_turbo_bytestore_source_end: From 51064f6b7086c51d0c78b67918d29940674f0bca Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 31 Jan 2020 20:58:07 +0100 Subject: [PATCH 29/66] implemented ROUND math routine, corrected some others --- STATUS.md | 1 + c64/basic/,stubs_math/bb12.interop | 3 +- c64/basic/,stubs_math/bcf3.interop | 3 +- c64/basic/,stubs_math/bddd.interop | 3 +- c64/basic/math/CONUPK.s | 2 +- c64/basic/math/MOVFM.s | 2 +- c64/basic/math/NORMAL.s | 6 +-- c64/basic/math/ROUND.s | 61 ++++++++++++++++++++++++++++++ c64/basic/math/bc1b.ROUND.jmp.s | 7 ++++ c64/basic/math/bc1b.interop | 4 ++ 10 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 c64/basic/math/ROUND.s create mode 100644 c64/basic/math/bc1b.ROUND.jmp.s create mode 100644 c64/basic/math/bc1b.interop diff --git a/STATUS.md b/STATUS.md index 8d4e76d4..3bd045d0 100644 --- a/STATUS.md +++ b/STATUS.md @@ -196,6 +196,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | | `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | | `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | +| `$BC1B` | `ROUND` | PARTIAL | not tested | | `$BC2B` | `SIGN` | NOT DONE | evaluate FAC1 sign | | `$BC39` | `SGN` | NOT DONE | evaluate FAC1 sign, to FAC1 | | `$BC58` | `ABS` | NOT DONE | absolute value | diff --git a/c64/basic/,stubs_math/bb12.interop b/c64/basic/,stubs_math/bb12.interop index 0d18777c..ba5a12d8 100644 --- a/c64/basic/,stubs_math/bb12.interop +++ b/c64/basic/,stubs_math/bb12.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing the routine: +- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 diff --git a/c64/basic/,stubs_math/bcf3.interop b/c64/basic/,stubs_math/bcf3.interop index 0d18777c..ba5a12d8 100644 --- a/c64/basic/,stubs_math/bcf3.interop +++ b/c64/basic/,stubs_math/bcf3.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing the routine: +- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 diff --git a/c64/basic/,stubs_math/bddd.interop b/c64/basic/,stubs_math/bddd.interop index 0d18777c..ba5a12d8 100644 --- a/c64/basic/,stubs_math/bddd.interop +++ b/c64/basic/,stubs_math/bddd.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing the routine: +- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 diff --git a/c64/basic/math/CONUPK.s b/c64/basic/math/CONUPK.s index a6ad4722..1b721579 100644 --- a/c64/basic/math/CONUPK.s +++ b/c64/basic/math/CONUPK.s @@ -38,7 +38,7 @@ CONUPK: // Now copy the data from RAM to FAC2, for the format description see: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 - // Copy the mantissa - reverse byte order + // Copy the mantissa ldy #$04 lda (INDEX), y diff --git a/c64/basic/math/MOVFM.s b/c64/basic/math/MOVFM.s index 9f6c510c..844aa6da 100644 --- a/c64/basic/math/MOVFM.s +++ b/c64/basic/math/MOVFM.s @@ -35,7 +35,7 @@ MOVMF: // Now copy the data from RAM to FAC2, for the format description see: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 - // Copy the mantissa - reverse byte order + // Copy the mantissa ldy #$04 lda (INDEX), y diff --git a/c64/basic/math/NORMAL.s b/c64/basic/math/NORMAL.s index f1e8fb61..6edbafde 100644 --- a/c64/basic/math/NORMAL.s +++ b/c64/basic/math/NORMAL.s @@ -44,10 +44,10 @@ normal_by_bit: clc rol FACOV - rol FAC1_mantissa+0 - rol FAC1_mantissa+1 - rol FAC1_mantissa+2 rol FAC1_mantissa+3 + rol FAC1_mantissa+2 + rol FAC1_mantissa+1 + rol FAC1_mantissa+0 bcc NORMAL // branch if next iteration needed rts diff --git a/c64/basic/math/ROUND.s b/c64/basic/math/ROUND.s new file mode 100644 index 00000000..b7706782 --- /dev/null +++ b/c64/basic/math/ROUND.s @@ -0,0 +1,61 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - rounds FAC1 before copying +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX test this + +ROUND: + + // If number is 0, do not do anything + + lda FAC1_exponent + beq round_done + + lda FACOV + bpl round_zero_FACOV // branch if it is enough to clear FACOV + + // Increment the 4 bytes of matissa + + // Curse you, who invented this format! Had the mantissa been little endian, + // we could have used INW on 65C02 and above, the code would have been smaller! + + inc FAC1_mantissa+3 + bne round_zero_FACOV + inc FAC1_mantissa+2 + bne round_zero_FACOV + inc FAC1_mantissa+1 + bne round_zero_FACOV + inc FAC1_mantissa+0 + bne round_zero_FACOV + + // If we are here, it means mantissa is 0; put it to minimum allowed and increment exponent + + lda #$80 + sta FAC1_mantissa+0 + inc FAC1_exponent + bne round_zero_FACOV + + // If w are here, it means the exponent wrapped around to $00; put it back to $FF + + dec FAC1_exponent + + // FALLTROUGH + +round_zero_FACOV: + + lda #$00 + sta FACOV + + // FALLTROUGH + +round_done: + + rts diff --git a/c64/basic/math/bc1b.ROUND.jmp.s b/c64/basic/math/bc1b.ROUND.jmp.s new file mode 100644 index 00000000..e6306152 --- /dev/null +++ b/c64/basic/math/bc1b.ROUND.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp ROUND diff --git a/c64/basic/math/bc1b.interop b/c64/basic/math/bc1b.interop new file mode 100644 index 00000000..ba5a12d8 --- /dev/null +++ b/c64/basic/math/bc1b.interop @@ -0,0 +1,4 @@ +This is an important floating point math routine, documented in many places. + +Example code utilizing the routine: +- https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 From a2cd07a94c268d7ee32e15fb598d91a7a47b9921 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 1 Feb 2020 20:52:00 +0100 Subject: [PATCH 30/66] implemented 2 more simple math routines --- STATUS.md | 5 +- .../{bbd4.MOVMF.s => bbd4.MOVMF2.s} | 3 +- c64/basic/math/MOVFA.s | 51 +++++++++++++++++++ c64/basic/math/MOVFM.s | 2 +- c64/basic/math/ROUND.s | 2 +- c64/basic/math/bba2.MOVFM.jmp.s | 2 +- .../bc0f.MOVFA.s => math/bc0c.MOVAF.s} | 15 ++++-- .../bc0f.interop => math/bc0c.interop} | 0 c64/basic/math/bc0f.MOVFA.jmp.s | 7 +++ c64/basic/math/bc0f.interop | 3 ++ 10 files changed, 78 insertions(+), 12 deletions(-) rename c64/basic/,stubs_math/{bbd4.MOVMF.s => bbd4.MOVMF2.s} (89%) create mode 100644 c64/basic/math/MOVFA.s rename c64/basic/{,stubs_math/bc0f.MOVFA.s => math/bc0c.MOVAF.s} (55%) rename c64/basic/{,stubs_math/bc0f.interop => math/bc0c.interop} (100%) create mode 100644 c64/basic/math/bc0f.MOVFA.jmp.s create mode 100644 c64/basic/math/bc0f.interop diff --git a/STATUS.md b/STATUS.md index 3bd045d0..73c892fc 100644 --- a/STATUS.md +++ b/STATUS.md @@ -193,9 +193,10 @@ Floating point mathematical routines - not official, but well known and broadly | `$BB0F` | `FDIV` | PARTIAL | needs `FDIVT` | | `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | | `$BBA2` | `MOVFM` | PARTIAL | not fully tested yet | -| `$BBD4` | `MOVMF` | NOT DONE | copy FAC1 to memory location, rounds if asked | +| `$BBD4` | `MOVFM2` | NOT DONE | copy FAC1 to memory location, rounds if asked | | `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | -| `$BC0F` | `MOVFA` | NOT DONE | copy FAC1 to FAC2, skips rounding | +| `$BC0C` | `MOVAF` | PARTIAL | not fully tested | +| `$BC0F` | `MOVFA` | DONE | | | `$BC1B` | `ROUND` | PARTIAL | not tested | | `$BC2B` | `SIGN` | NOT DONE | evaluate FAC1 sign | | `$BC39` | `SGN` | NOT DONE | evaluate FAC1 sign, to FAC1 | diff --git a/c64/basic/,stubs_math/bbd4.MOVMF.s b/c64/basic/,stubs_math/bbd4.MOVMF2.s similarity index 89% rename from c64/basic/,stubs_math/bbd4.MOVMF.s rename to c64/basic/,stubs_math/bbd4.MOVMF2.s index 4a7a3d60..850adaa5 100644 --- a/c64/basic/,stubs_math/bbd4.MOVMF.s +++ b/c64/basic/,stubs_math/bbd4.MOVMF2.s @@ -14,12 +14,11 @@ // - .A - FAC1 exponent // // See also: -// - [CM64] Computes Mapping the Commodore 64 - page 114 // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // // XXX provide implementation -MOVFM: +MOVFM2: STUB_IMPLEMENTATION() diff --git a/c64/basic/math/MOVFA.s b/c64/basic/math/MOVFA.s new file mode 100644 index 00000000..afc70c4e --- /dev/null +++ b/c64/basic/math/MOVFA.s @@ -0,0 +1,51 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - move FAC1 to FAC2 +// +// Output (all found by experimentation): +// - .A - FAC1 exponent +// - .X - always 0 +// +// Preserves (found by experimentation): +// - .Y +// +// Note: +// - observed that original ROM always clears FACOV, not sure why +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// + +MOVFA: + + // Copy the exponent + lda FAC1_exponent + sta FAC2_exponent + beq !+ // for 0 no need to copy mantissa and sign + + // Copy the mantissa + lda FAC1_mantissa+0 + sta FAC2_mantissa+0 + lda FAC1_mantissa+1 + sta FAC2_mantissa+1 + lda FAC1_mantissa+2 + sta FAC2_mantissa+2 + lda FAC1_mantissa+3 + sta FAC2_mantissa+3 + + // Copy the sign + lda FAC1_sign + sta FAC2_sign + + lda FAC1_exponent +!: + // Duplicate the original ROM behaviour + ldx #$00 + stx FACOV + + rts diff --git a/c64/basic/math/MOVFM.s b/c64/basic/math/MOVFM.s index 844aa6da..93090f85 100644 --- a/c64/basic/math/MOVFM.s +++ b/c64/basic/math/MOVFM.s @@ -21,7 +21,7 @@ // XXX test this -MOVMF: +MOVFM: // Checked in the available documentation: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic diff --git a/c64/basic/math/ROUND.s b/c64/basic/math/ROUND.s index b7706782..c044abf4 100644 --- a/c64/basic/math/ROUND.s +++ b/c64/basic/math/ROUND.s @@ -43,7 +43,7 @@ ROUND: inc FAC1_exponent bne round_zero_FACOV - // If w are here, it means the exponent wrapped around to $00; put it back to $FF + // If we are here, it means the exponent wrapped around to $00; put it back to $FF dec FAC1_exponent diff --git a/c64/basic/math/bba2.MOVFM.jmp.s b/c64/basic/math/bba2.MOVFM.jmp.s index d62c457d..424296fb 100644 --- a/c64/basic/math/bba2.MOVFM.jmp.s +++ b/c64/basic/math/bba2.MOVFM.jmp.s @@ -4,4 +4,4 @@ // Just a compatibility jump - our routine is longer than original one - jmp MOVMF + jmp MOVFM diff --git a/c64/basic/,stubs_math/bc0f.MOVFA.s b/c64/basic/math/bc0c.MOVAF.s similarity index 55% rename from c64/basic/,stubs_math/bc0f.MOVFA.s rename to c64/basic/math/bc0c.MOVAF.s index fbc9087e..9f0d836e 100644 --- a/c64/basic/,stubs_math/bc0f.MOVFA.s +++ b/c64/basic/math/bc0c.MOVAF.s @@ -3,15 +3,20 @@ // #LAYOUT# * * #IGNORE // -// Math package - copy FAC1 to FAC2, skips rounding +// Math package - round and move FAC1 to FAC2 +// +// Output: +// - .A - FAC1 exponent // // See also: // - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/BASIC-ROM // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation +MOVAF: -MOVFA: - STUB_IMPLEMENTATION() + // First round FAC1 + jsr ROUND + + // FALLTROUGH to MOVFA \ No newline at end of file diff --git a/c64/basic/,stubs_math/bc0f.interop b/c64/basic/math/bc0c.interop similarity index 100% rename from c64/basic/,stubs_math/bc0f.interop rename to c64/basic/math/bc0c.interop diff --git a/c64/basic/math/bc0f.MOVFA.jmp.s b/c64/basic/math/bc0f.MOVFA.jmp.s new file mode 100644 index 00000000..e4efb535 --- /dev/null +++ b/c64/basic/math/bc0f.MOVFA.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp MOVFA diff --git a/c64/basic/math/bc0f.interop b/c64/basic/math/bc0f.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bc0f.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example From 4673f825afcbed1dbbe5ee9f2857b06e64d094f5 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 1 Feb 2020 22:01:14 +0100 Subject: [PATCH 31/66] naming cleanup in math routines --- STATUS.md | 90 +++++++++---------- .../{b86a.FADDT.s => b86a.add_FAC2_FAC1.s} | 2 +- .../{b9ea.LOG.s => b9ea.log_FAC1.s} | 2 +- .../{ba2b.FMULT.s => ba2b.mul_FAC2_FAC1.s} | 2 +- .../{bae2.MUL10.s => bae2.mul10_FAC1.s} | 2 +- .../{bafe.DIV10.s => bafe.div10_FAC1_p.s} | 2 +- .../{bb12.FDIVT.s => bb12.div_FAC2_FAC1.s} | 2 +- .../{bc2b.SIGN.s => bc2b.sgn_FAC1_A.s} | 2 +- .../{bc39.SGN.s => bc39.sgn_FAC1.s} | 2 +- .../{bc58.ABS.s => bc58.abs_FAC1.s} | 2 +- .../{bccc.INT.s => bccc.int_FAC1.s} | 2 +- .../{bf71.SQR.s => bf71.sqr_FAC1.s} | 2 +- .../{bf74.SQR2.s => bf74.sqr_FAC2.s} | 2 +- .../{bfed.EXP.s => bfed.exp_FAC1.s} | 2 +- .../{e043.POLY1.s => e043.poly1_FAC1.s} | 2 +- .../{e059.POLY2.s => e059.poly2_FAC1.s} | 2 +- .../{e264.COS.s => e264.cos_FAC1.s} | 0 .../{e26b.SIN.s => e26b.sin_FAC1.s} | 2 +- .../{e2b4.TAN.s => e2b4.tan_FAC1.s} | 2 +- .../{e30e.ATN.s => e30e.atn_FAC1.s} | 2 +- .../math/{b867.FADD.s => b850.sub_MEM_FAC1.s} | 8 +- c64/basic/{,stubs_math => math}/b853.interop | 0 .../b853.sub_FAC2_FAC1.s} | 19 ++-- .../math/{b850.FSUB.s => b867.add_MEM_FAC1.s} | 8 +- ...fe.NORMAL.jmp.s => b8fe.normal_FAC1.jmp.s} | 2 +- .../math/{ba28.FMUL.s => ba28.mul_MEM_FAC1.s} | 6 +- ...c.CONUPK.jmp.s => ba8c.mov_MEM_FAC2.jmp.s} | 2 +- .../math/{bb0f.FDIV.s => bb0f.div_MEM_FAC1.s} | 6 +- ...a2.MOVFM.jmp.s => bba2.mov_MEM_FAC1.jmp.s} | 2 +- .../{bc0c.MOVAF.s => bc0c.mov_r_FAC1_FAC2.s} | 6 +- c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s | 7 ++ c64/basic/math/bc1b.ROUND.jmp.s | 7 -- ...bc0f.MOVFA.jmp.s => bc1b.round_FAC1.jmp.s} | 3 +- .../{bfb4.NEGOP.s => bfb4.toggle_sign_FAC1.s} | 2 +- c64/basic/math/{MOVFA.s => mov_FAC1_FAC2.s} | 2 +- c64/basic/math/{MOVFM.s => mov_MEM_FAC1.s} | 2 +- c64/basic/math/{CONUPK.s => mov_MEM_FAC2.s} | 4 +- c64/basic/math/{NORMAL.s => normal_FAC1.s} | 20 ++--- c64/basic/math/{ROUND.s => round_FAC1.s} | 20 ++--- 39 files changed, 127 insertions(+), 125 deletions(-) rename c64/basic/,stubs_math/{b86a.FADDT.s => b86a.add_FAC2_FAC1.s} (97%) rename c64/basic/,stubs_math/{b9ea.LOG.s => b9ea.log_FAC1.s} (97%) rename c64/basic/,stubs_math/{ba2b.FMULT.s => ba2b.mul_FAC2_FAC1.s} (97%) rename c64/basic/,stubs_math/{bae2.MUL10.s => bae2.mul10_FAC1.s} (97%) rename c64/basic/,stubs_math/{bafe.DIV10.s => bafe.div10_FAC1_p.s} (97%) rename c64/basic/,stubs_math/{bb12.FDIVT.s => bb12.div_FAC2_FAC1.s} (97%) rename c64/basic/,stubs_math/{bc2b.SIGN.s => bc2b.sgn_FAC1_A.s} (97%) rename c64/basic/,stubs_math/{bc39.SGN.s => bc39.sgn_FAC1.s} (98%) rename c64/basic/,stubs_math/{bc58.ABS.s => bc58.abs_FAC1.s} (97%) rename c64/basic/,stubs_math/{bccc.INT.s => bccc.int_FAC1.s} (97%) rename c64/basic/,stubs_math/{bf71.SQR.s => bf71.sqr_FAC1.s} (97%) rename c64/basic/,stubs_math/{bf74.SQR2.s => bf74.sqr_FAC2.s} (98%) rename c64/basic/,stubs_math/{bfed.EXP.s => bfed.exp_FAC1.s} (97%) rename c64/basic/,stubs_math/{e043.POLY1.s => e043.poly1_FAC1.s} (98%) rename c64/basic/,stubs_math/{e059.POLY2.s => e059.poly2_FAC1.s} (98%) rename c64/basic/,stubs_math/{e264.COS.s => e264.cos_FAC1.s} (100%) rename c64/basic/,stubs_math/{e26b.SIN.s => e26b.sin_FAC1.s} (97%) rename c64/basic/,stubs_math/{e2b4.TAN.s => e2b4.tan_FAC1.s} (97%) rename c64/basic/,stubs_math/{e30e.ATN.s => e30e.atn_FAC1.s} (97%) rename c64/basic/math/{b867.FADD.s => b850.sub_MEM_FAC1.s} (76%) rename c64/basic/{,stubs_math => math}/b853.interop (100%) rename c64/basic/{,stubs_math/b853.FSUBT.s => math/b853.sub_FAC2_FAC1.s} (59%) rename c64/basic/math/{b850.FSUB.s => b867.add_MEM_FAC1.s} (77%) rename c64/basic/math/{b8fe.NORMAL.jmp.s => b8fe.normal_FAC1.jmp.s} (90%) rename c64/basic/math/{ba28.FMUL.s => ba28.mul_MEM_FAC1.s} (88%) rename c64/basic/math/{ba8c.CONUPK.jmp.s => ba8c.mov_MEM_FAC2.jmp.s} (90%) rename c64/basic/math/{bb0f.FDIV.s => bb0f.div_MEM_FAC1.s} (86%) rename c64/basic/math/{bba2.MOVFM.jmp.s => bba2.mov_MEM_FAC1.jmp.s} (90%) rename c64/basic/math/{bc0c.MOVAF.s => bc0c.mov_r_FAC1_FAC2.s} (85%) create mode 100644 c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s delete mode 100644 c64/basic/math/bc1b.ROUND.jmp.s rename c64/basic/math/{bc0f.MOVFA.jmp.s => bc1b.round_FAC1.jmp.s} (90%) rename c64/basic/math/{bfb4.NEGOP.s => bfb4.toggle_sign_FAC1.s} (95%) rename c64/basic/math/{MOVFA.s => mov_FAC1_FAC2.s} (98%) rename c64/basic/math/{MOVFM.s => mov_MEM_FAC1.s} (99%) rename c64/basic/math/{CONUPK.s => mov_MEM_FAC2.s} (96%) rename c64/basic/math/{NORMAL.s => normal_FAC1.s} (74%) rename c64/basic/math/{ROUND.s => round_FAC1.s} (77%) diff --git a/STATUS.md b/STATUS.md index 73c892fc..9b2d1f73 100644 --- a/STATUS.md +++ b/STATUS.md @@ -170,54 +170,54 @@ For the current status of the low memory location implementation andd usage chec ### Math package -Floating point mathematical routines - not official, but well known and broadly used. +Floating point mathematical routines - not official, but well known and broadly used. Note: there is an awful mess regarding naming (sometimes same name references different routines in different sources), so a custom naming scheme was applied.
-| Address | Name | Status | Remarks | -| :-------: | :----------- | :------: | :------------------------------------------------: | -| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | -| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | -| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | -| `$B850` | `FSUB` | PARTIAL | needs `FSUBT` | -| `$B853` | `FSUBT` | NOT DONE | subtract FAC1 from FAC2 | -| `$B867` | `FADD` | PARTIAL | needs `FADDT` | -| `$B86A` | `FADDT` | NOT DONE | add FAC2 to FAC1 | -| `$B8FE` | `NORMAL` | PARTIAL | not tested yet | -| `$B9EA` | `LOG` | NOT DONE | natural logarigthm | -| `$BA28` | `FMUL` | PARTIAL | needs `FMULT` | -| `$BA2B` | `FMULT` | NOT DONE | multiplies FAC1 by FAC2 | -| `$BA8C` | `CONUPK` | PARTIAL | not fully tested yet | -| `$BAE2` | `MUL10` | NOT DONE | multiply FAC1 by 10 | -| `$BAFE` | `DIV10` | NOT DONE | divide FAC1 by 10, result is always positive | -| `$BB0F` | `FDIV` | PARTIAL | needs `FDIVT` | -| `$BB12` | `FDIVT` | NOT DONE | divide FAC2 by FAC1, ignores sign | -| `$BBA2` | `MOVFM` | PARTIAL | not fully tested yet | -| `$BBD4` | `MOVFM2` | NOT DONE | copy FAC1 to memory location, rounds if asked | -| `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | -| `$BC0C` | `MOVAF` | PARTIAL | not fully tested | -| `$BC0F` | `MOVFA` | DONE | | -| `$BC1B` | `ROUND` | PARTIAL | not tested | -| `$BC2B` | `SIGN` | NOT DONE | evaluate FAC1 sign | -| `$BC39` | `SGN` | NOT DONE | evaluate FAC1 sign, to FAC1 | -| `$BC58` | `ABS` | NOT DONE | absolute value | -| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | -| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | -| `$BCCC` | `INT` | NOT DONE | rounds away the decimal to make an integer | -| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | -| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | -| `$BF71` | `SQR` | NOT DONE | square root of FAC1 | -| `$BF74` | `SQR2` | NOT DONE | square root of FAC2 | -| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | -| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | -| `$BFB4` | `NEGOP` | DONE | | -| `$BFED` | `EXP` | NOT DONE | exponential function, e raised to FAC1 power | -| `$E043` | `POLY1` | NOT DONE | evaluate polynomial with odd powers only | -| `$E059` | `POLY2` | NOT DONE | evaluate polynomial with odd and even powers | -| `$E264` | `COS` | NOT DONE | cosine of FAC1 in radians | -| `$E26B` | `SIN` | NOT DONE | sine of FAC1 in radians | -| `$E2B4` | `TAN` | NOT DONE | tangent of FAC1 in radians | -| `$E30E` | `ATN` | NOT DONE | arc tangent of FAC1 | +| Address | Name | Status | Remarks | +| :-------: | :----------------- | :------: | :------------------------------------------------: | +| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | +| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | +| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | +| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `sub_FAC2_FAC1` | +| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | +| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | +| `$B9EA` | `log_FAC1` | NOT DONE | | +| `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | +| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | +| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | +| `$BAE2` | `mul10_FAC1` | NOT DONE | | +| `$BAFE` | `div10_FAC1_p` | NOT DONE | | +| `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | +| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | +| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | +| `$BBD4` | `MOVFM2` | NOT DONE | copy FAC1 to memory location, rounds if asked | +| `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | +| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested | +| `$BC0F` | `mov_FAC1_FAC2` | DONE | | +| `$BC1B` | `round_FAC1` | PARTIAL | not tested | +| `$BC2B` | `sgn_FAC1_A` | NOT DONE | | +| `$BC39` | `sgn_FAC1` | NOT DONE | | +| `$BC58` | `abs_FAC1` | NOT DONE | | +| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | +| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | +| `$BCCC` | `int_FAC1` | NOT DONE | | +| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | +| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | +| `$BF71` | `sqr_FAC1` | NOT DONE | | +| `$BF74` | `sqr_FAC2` | NOT DONE | | +| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | +| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | +| `$BFB4` | `toggle_sign_FAC1` | DONE | | +| `$BFED` | `exp_FAC1` | NOT DONE | | +| `$E043` | `poly1_FAC1` | NOT DONE | | +| `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E264` | `cos_FAC1` | NOT DONE | | +| `$E26B` | `sin_FAC1` | NOT DONE | | +| `$E2B4` | `tan_FAC1` | NOT DONE | | +| `$E30E` | `atn_FAC1` | NOT DONE | |
diff --git a/c64/basic/,stubs_math/b86a.FADDT.s b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/b86a.FADDT.s rename to c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s index c48274a3..a88305d8 100644 --- a/c64/basic/,stubs_math/b86a.FADDT.s +++ b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s @@ -19,5 +19,5 @@ // XXX provide implementation -FADDT: +add_FAC2_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b9ea.LOG.s b/c64/basic/,stubs_math/b9ea.log_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/b9ea.LOG.s rename to c64/basic/,stubs_math/b9ea.log_FAC1.s index 3fc121a7..295fdf19 100644 --- a/c64/basic/,stubs_math/b9ea.LOG.s +++ b/c64/basic/,stubs_math/b9ea.log_FAC1.s @@ -14,5 +14,5 @@ // XXX provide implementation -LOG: +log_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba2b.FMULT.s b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/ba2b.FMULT.s rename to c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s index 0344f167..bc78e2fb 100644 --- a/c64/basic/,stubs_math/ba2b.FMULT.s +++ b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s @@ -19,5 +19,5 @@ // XXX provide implementation -FMULT: +mul_FAC2_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bae2.MUL10.s b/c64/basic/,stubs_math/bae2.mul10_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bae2.MUL10.s rename to c64/basic/,stubs_math/bae2.mul10_FAC1.s index 3fde16d3..8413a242 100644 --- a/c64/basic/,stubs_math/bae2.MUL10.s +++ b/c64/basic/,stubs_math/bae2.mul10_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -MUL10: +mul10_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bafe.DIV10.s b/c64/basic/,stubs_math/bafe.div10_FAC1_p.s similarity index 97% rename from c64/basic/,stubs_math/bafe.DIV10.s rename to c64/basic/,stubs_math/bafe.div10_FAC1_p.s index 3d59810d..e3cc5252 100644 --- a/c64/basic/,stubs_math/bafe.DIV10.s +++ b/c64/basic/,stubs_math/bafe.div10_FAC1_p.s @@ -17,5 +17,5 @@ // XXX provide implementation -DIV10: +div10_FAC1_p: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bb12.FDIVT.s b/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bb12.FDIVT.s rename to c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s index d02ef219..987eed74 100644 --- a/c64/basic/,stubs_math/bb12.FDIVT.s +++ b/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s @@ -19,5 +19,5 @@ // XXX provide implementation -FDIVT: +div_FAC2_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc2b.SIGN.s b/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s similarity index 97% rename from c64/basic/,stubs_math/bc2b.SIGN.s rename to c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s index 151b25d5..b5e630c5 100644 --- a/c64/basic/,stubs_math/bc2b.SIGN.s +++ b/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s @@ -16,5 +16,5 @@ // XXX provide implementation -SIGN: +sgn_FAC1_A: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc39.SGN.s b/c64/basic/,stubs_math/bc39.sgn_FAC1.s similarity index 98% rename from c64/basic/,stubs_math/bc39.SGN.s rename to c64/basic/,stubs_math/bc39.sgn_FAC1.s index 1b53f34c..ca081a8e 100644 --- a/c64/basic/,stubs_math/bc39.SGN.s +++ b/c64/basic/,stubs_math/bc39.sgn_FAC1.s @@ -16,5 +16,5 @@ // XXX provide implementation -SGN: +sgn_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc58.ABS.s b/c64/basic/,stubs_math/bc58.abs_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bc58.ABS.s rename to c64/basic/,stubs_math/bc58.abs_FAC1.s index a152eb7e..2d4117c6 100644 --- a/c64/basic/,stubs_math/bc58.ABS.s +++ b/c64/basic/,stubs_math/bc58.abs_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -ABS: +abs_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bccc.INT.s b/c64/basic/,stubs_math/bccc.int_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bccc.INT.s rename to c64/basic/,stubs_math/bccc.int_FAC1.s index a693a85d..ad25b646 100644 --- a/c64/basic/,stubs_math/bccc.INT.s +++ b/c64/basic/,stubs_math/bccc.int_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -INT: +int_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf71.SQR.s b/c64/basic/,stubs_math/bf71.sqr_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bf71.SQR.s rename to c64/basic/,stubs_math/bf71.sqr_FAC1.s index 4e1a3115..ca2091c3 100644 --- a/c64/basic/,stubs_math/bf71.SQR.s +++ b/c64/basic/,stubs_math/bf71.sqr_FAC1.s @@ -16,5 +16,5 @@ // XXX provide implementation -SQR: +sqr_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bf74.SQR2.s b/c64/basic/,stubs_math/bf74.sqr_FAC2.s similarity index 98% rename from c64/basic/,stubs_math/bf74.SQR2.s rename to c64/basic/,stubs_math/bf74.sqr_FAC2.s index abf1fc2d..ab99c98f 100644 --- a/c64/basic/,stubs_math/bf74.SQR2.s +++ b/c64/basic/,stubs_math/bf74.sqr_FAC2.s @@ -16,5 +16,5 @@ // XXX provide implementation -SQR2: +sqr_FAC2: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bfed.EXP.s b/c64/basic/,stubs_math/bfed.exp_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/bfed.EXP.s rename to c64/basic/,stubs_math/bfed.exp_FAC1.s index 7ad24634..9e392ad8 100644 --- a/c64/basic/,stubs_math/bfed.EXP.s +++ b/c64/basic/,stubs_math/bfed.exp_FAC1.s @@ -14,5 +14,5 @@ // XXX provide implementation -EXP: +exp_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e043.POLY1.s b/c64/basic/,stubs_math/e043.poly1_FAC1.s similarity index 98% rename from c64/basic/,stubs_math/e043.POLY1.s rename to c64/basic/,stubs_math/e043.poly1_FAC1.s index c4042bc8..94639620 100644 --- a/c64/basic/,stubs_math/e043.POLY1.s +++ b/c64/basic/,stubs_math/e043.poly1_FAC1.s @@ -23,5 +23,5 @@ // XXX provide implementation -POLY1: +poly1_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e059.POLY2.s b/c64/basic/,stubs_math/e059.poly2_FAC1.s similarity index 98% rename from c64/basic/,stubs_math/e059.POLY2.s rename to c64/basic/,stubs_math/e059.poly2_FAC1.s index b2d94100..226c61b3 100644 --- a/c64/basic/,stubs_math/e059.POLY2.s +++ b/c64/basic/,stubs_math/e059.poly2_FAC1.s @@ -23,5 +23,5 @@ // XXX provide implementation -POLY2: +poly2_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e264.COS.s b/c64/basic/,stubs_math/e264.cos_FAC1.s similarity index 100% rename from c64/basic/,stubs_math/e264.COS.s rename to c64/basic/,stubs_math/e264.cos_FAC1.s diff --git a/c64/basic/,stubs_math/e26b.SIN.s b/c64/basic/,stubs_math/e26b.sin_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/e26b.SIN.s rename to c64/basic/,stubs_math/e26b.sin_FAC1.s index 5ca46126..99eb4569 100644 --- a/c64/basic/,stubs_math/e26b.SIN.s +++ b/c64/basic/,stubs_math/e26b.sin_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -SIN: +sin_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e2b4.TAN.s b/c64/basic/,stubs_math/e2b4.tan_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/e2b4.TAN.s rename to c64/basic/,stubs_math/e2b4.tan_FAC1.s index d0cc416d..480991fc 100644 --- a/c64/basic/,stubs_math/e2b4.TAN.s +++ b/c64/basic/,stubs_math/e2b4.tan_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -TAN: +tan_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/e30e.ATN.s b/c64/basic/,stubs_math/e30e.atn_FAC1.s similarity index 97% rename from c64/basic/,stubs_math/e30e.ATN.s rename to c64/basic/,stubs_math/e30e.atn_FAC1.s index 642cea97..1fc04501 100644 --- a/c64/basic/,stubs_math/e30e.ATN.s +++ b/c64/basic/,stubs_math/e30e.atn_FAC1.s @@ -13,5 +13,5 @@ // XXX provide implementation -ATN: +atn_FAC1: STUB_IMPLEMENTATION() diff --git a/c64/basic/math/b867.FADD.s b/c64/basic/math/b850.sub_MEM_FAC1.s similarity index 76% rename from c64/basic/math/b867.FADD.s rename to c64/basic/math/b850.sub_MEM_FAC1.s index e5bd97b3..a5f15869 100644 --- a/c64/basic/math/b867.FADD.s +++ b/c64/basic/math/b850.sub_MEM_FAC1.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// Math package - add RAM to FAC1 +// Math package - subtract FAC1 from memory variable // // Input: // - .A - address low byte @@ -15,8 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -FADD: +sub_MEM_FAC1: - jsr CONUPK + jsr mov_MEM_FAC2 - // FALLTROUGH to FADDT + // FALLTROUGH to sub_FAC2_FAC1 diff --git a/c64/basic/,stubs_math/b853.interop b/c64/basic/math/b853.interop similarity index 100% rename from c64/basic/,stubs_math/b853.interop rename to c64/basic/math/b853.interop diff --git a/c64/basic/,stubs_math/b853.FSUBT.s b/c64/basic/math/b853.sub_FAC2_FAC1.s similarity index 59% rename from c64/basic/,stubs_math/b853.FSUBT.s rename to c64/basic/math/b853.sub_FAC2_FAC1.s index 58b4a4db..49f699e9 100644 --- a/c64/basic/,stubs_math/b853.FSUBT.s +++ b/c64/basic/math/b853.sub_FAC2_FAC1.s @@ -5,19 +5,20 @@ // // Math package - subtract FAC1 from FAC2 // -// Input: -// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag -// -// Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) -// // See also: // - [CM64] Computes Mapping the Commodore 64 - page 112 // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation +// XXX test this -FSUBT: - STUB_IMPLEMENTATION() +sub_FAC2_FAC1: + + // Toggle FAC1 sign + lda FAC1_sign + eor #$FF + sta FAC1_sign + + // Perform addition + jmp add_FAC2_FAC1 diff --git a/c64/basic/math/b850.FSUB.s b/c64/basic/math/b867.add_MEM_FAC1.s similarity index 77% rename from c64/basic/math/b850.FSUB.s rename to c64/basic/math/b867.add_MEM_FAC1.s index ca6d9488..9ed42325 100644 --- a/c64/basic/math/b850.FSUB.s +++ b/c64/basic/math/b867.add_MEM_FAC1.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// Math package - subtract FAC1 from RAM +// Math package - add memory variable to FAC1 // // Input: // - .A - address low byte @@ -15,8 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -FSUB: +add_MEM_FAC1: - jsr CONUPK + jsr mov_MEM_FAC2 - // FALLTROUGH to FSUBT + // FALLTROUGH to add_FAC2_FAC1 diff --git a/c64/basic/math/b8fe.NORMAL.jmp.s b/c64/basic/math/b8fe.normal_FAC1.jmp.s similarity index 90% rename from c64/basic/math/b8fe.NORMAL.jmp.s rename to c64/basic/math/b8fe.normal_FAC1.jmp.s index 7c5c26b8..a9fd1d5c 100644 --- a/c64/basic/math/b8fe.NORMAL.jmp.s +++ b/c64/basic/math/b8fe.normal_FAC1.jmp.s @@ -4,4 +4,4 @@ // Just a compatibility jump - our routine is longer than original one - jmp NORMAL + jmp normal_FAC1 diff --git a/c64/basic/math/ba28.FMUL.s b/c64/basic/math/ba28.mul_MEM_FAC1.s similarity index 88% rename from c64/basic/math/ba28.FMUL.s rename to c64/basic/math/ba28.mul_MEM_FAC1.s index 3e02237a..3a5c5f08 100644 --- a/c64/basic/math/ba28.FMUL.s +++ b/c64/basic/math/ba28.mul_MEM_FAC1.s @@ -18,8 +18,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -FMUL: +mul_MEM_FAC1: - jsr CONUPK + jsr mov_MEM_FAC2 - // FALLTROUGH to FMULT + // FALLTROUGH to mul_FAC2_FAC1 diff --git a/c64/basic/math/ba8c.CONUPK.jmp.s b/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s similarity index 90% rename from c64/basic/math/ba8c.CONUPK.jmp.s rename to c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s index 53809055..2e2bdffc 100644 --- a/c64/basic/math/ba8c.CONUPK.jmp.s +++ b/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s @@ -4,4 +4,4 @@ // Just a compatibility jump - our routine is longer than original one - jmp CONUPK + jmp mov_MEM_FAC2 diff --git a/c64/basic/math/bb0f.FDIV.s b/c64/basic/math/bb0f.div_MEM_FAC1.s similarity index 86% rename from c64/basic/math/bb0f.FDIV.s rename to c64/basic/math/bb0f.div_MEM_FAC1.s index cce82469..37fc4c6a 100644 --- a/c64/basic/math/bb0f.FDIV.s +++ b/c64/basic/math/bb0f.div_MEM_FAC1.s @@ -15,8 +15,8 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -FDIV: +div_MEM_FAC1: - jsr CONUPK + jsr mov_MEM_FAC2 - // FALLTROUGH to FDIVT + // FALLTROUGH to div_FAC2_FAC1 diff --git a/c64/basic/math/bba2.MOVFM.jmp.s b/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s similarity index 90% rename from c64/basic/math/bba2.MOVFM.jmp.s rename to c64/basic/math/bba2.mov_MEM_FAC1.jmp.s index 424296fb..71b6fe4a 100644 --- a/c64/basic/math/bba2.MOVFM.jmp.s +++ b/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s @@ -4,4 +4,4 @@ // Just a compatibility jump - our routine is longer than original one - jmp MOVFM + jmp mov_MEM_FAC1 diff --git a/c64/basic/math/bc0c.MOVAF.s b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s similarity index 85% rename from c64/basic/math/bc0c.MOVAF.s rename to c64/basic/math/bc0c.mov_r_FAC1_FAC2.s index 9f0d836e..6dd59663 100644 --- a/c64/basic/math/bc0c.MOVAF.s +++ b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s @@ -14,9 +14,9 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -MOVAF: +movr_FAC1_FAC2: // First round FAC1 - jsr ROUND + jsr round_FAC1 - // FALLTROUGH to MOVFA \ No newline at end of file + // FALLTROUGH to mov_FAC1_FAC2 diff --git a/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s b/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s new file mode 100644 index 00000000..dde35453 --- /dev/null +++ b/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_FAC1_FAC2 diff --git a/c64/basic/math/bc1b.ROUND.jmp.s b/c64/basic/math/bc1b.ROUND.jmp.s deleted file mode 100644 index e6306152..00000000 --- a/c64/basic/math/bc1b.ROUND.jmp.s +++ /dev/null @@ -1,7 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// Just a compatibility jump - our routine is longer than original one - - jmp ROUND diff --git a/c64/basic/math/bc0f.MOVFA.jmp.s b/c64/basic/math/bc1b.round_FAC1.jmp.s similarity index 90% rename from c64/basic/math/bc0f.MOVFA.jmp.s rename to c64/basic/math/bc1b.round_FAC1.jmp.s index e4efb535..1c04b38e 100644 --- a/c64/basic/math/bc0f.MOVFA.jmp.s +++ b/c64/basic/math/bc1b.round_FAC1.jmp.s @@ -4,4 +4,5 @@ // Just a compatibility jump - our routine is longer than original one - jmp MOVFA + jmp round_FAC1 + diff --git a/c64/basic/math/bfb4.NEGOP.s b/c64/basic/math/bfb4.toggle_sign_FAC1.s similarity index 95% rename from c64/basic/math/bfb4.NEGOP.s rename to c64/basic/math/bfb4.toggle_sign_FAC1.s index c231407b..bfa61cc5 100644 --- a/c64/basic/math/bfb4.NEGOP.s +++ b/c64/basic/math/bfb4.toggle_sign_FAC1.s @@ -10,7 +10,7 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -NEGOP: +toggle_sign_FAC1: lda FAC1_exponent beq !+ // do not toggle the sign if value is 0 diff --git a/c64/basic/math/MOVFA.s b/c64/basic/math/mov_FAC1_FAC2.s similarity index 98% rename from c64/basic/math/MOVFA.s rename to c64/basic/math/mov_FAC1_FAC2.s index afc70c4e..8ce497d5 100644 --- a/c64/basic/math/MOVFA.s +++ b/c64/basic/math/mov_FAC1_FAC2.s @@ -21,7 +21,7 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -MOVFA: +mov_FAC1_FAC2: // Copy the exponent lda FAC1_exponent diff --git a/c64/basic/math/MOVFM.s b/c64/basic/math/mov_MEM_FAC1.s similarity index 99% rename from c64/basic/math/MOVFM.s rename to c64/basic/math/mov_MEM_FAC1.s index 93090f85..14ceb648 100644 --- a/c64/basic/math/MOVFM.s +++ b/c64/basic/math/mov_MEM_FAC1.s @@ -21,7 +21,7 @@ // XXX test this -MOVFM: +mov_MEM_FAC1: // Checked in the available documentation: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic diff --git a/c64/basic/math/CONUPK.s b/c64/basic/math/mov_MEM_FAC2.s similarity index 96% rename from c64/basic/math/CONUPK.s rename to c64/basic/math/mov_MEM_FAC2.s index 1b721579..0258c041 100644 --- a/c64/basic/math/CONUPK.s +++ b/c64/basic/math/mov_MEM_FAC2.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// Math package - fetch FAC2 from RAM location +// Math package - fetch FAC2 from memory location // // Input: // - .A - address low byte @@ -24,7 +24,7 @@ // XXX test this -CONUPK: +mov_MEM_FAC2: // Checked in the available documentation: // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic diff --git a/c64/basic/math/NORMAL.s b/c64/basic/math/normal_FAC1.s similarity index 74% rename from c64/basic/math/NORMAL.s rename to c64/basic/math/normal_FAC1.s index 6edbafde..0dda7581 100644 --- a/c64/basic/math/NORMAL.s +++ b/c64/basic/math/normal_FAC1.s @@ -13,20 +13,20 @@ // XXX test this -NORMAL: +normal_FAC1: lda FAC1_exponent - beq normal_end // branch if our float is 0 + beq normal_FAC1_end // branch if our float is 0 lda FAC1_mantissa+3 - beq normal_by_byte // branch if we can move the whole byte + beq normal_FAC1_by_byte // branch if we can move the whole byte and #$80 - bne normal_end // branch if already normalized + bne normal_FAC1_end // branch if already normalized // FALLTROUGH -normal_by_bit: +normal_FAC1_by_bit: // First check the current exponent @@ -49,10 +49,10 @@ normal_by_bit: rol FAC1_mantissa+1 rol FAC1_mantissa+0 - bcc NORMAL // branch if next iteration needed + bcc normal_FAC1 // branch if next iteration needed rts -normal_by_byte: +normal_FAC1_by_byte: // First decrement the exponent by 8, but not below 0 @@ -63,7 +63,7 @@ normal_by_byte: lda #$00 !: sta FAC1_exponent - beq normal_end // branch if our float reached 0 + beq normal_FAC1_end // branch if our float reached 0 // Now multiply the mantissa by 8 by moving the whole bytes @@ -87,7 +87,7 @@ normal_by_byte: ora FAC1_mantissa+2 ora FAC1_mantissa+3 - bne NORMAL // not 0 - branch to next iteration + bne normal_FAC1 // not 0 - branch to next iteration // Our mantissa reached 0 - mark exponent as 0 and finish @@ -95,6 +95,6 @@ normal_by_byte: // FALLTROUGH -normal_end: +normal_FAC1_end: rts diff --git a/c64/basic/math/ROUND.s b/c64/basic/math/round_FAC1.s similarity index 77% rename from c64/basic/math/ROUND.s rename to c64/basic/math/round_FAC1.s index c044abf4..7cef4a05 100644 --- a/c64/basic/math/ROUND.s +++ b/c64/basic/math/round_FAC1.s @@ -12,15 +12,15 @@ // XXX test this -ROUND: +round_FAC1: // If number is 0, do not do anything lda FAC1_exponent - beq round_done + beq round_FAC1_done lda FACOV - bpl round_zero_FACOV // branch if it is enough to clear FACOV + bpl round_FAC1_zero_FACOV // branch if it is enough to clear FACOV // Increment the 4 bytes of matissa @@ -28,20 +28,20 @@ ROUND: // we could have used INW on 65C02 and above, the code would have been smaller! inc FAC1_mantissa+3 - bne round_zero_FACOV + bne round_FAC1_zero_FACOV inc FAC1_mantissa+2 - bne round_zero_FACOV + bne round_FAC1_zero_FACOV inc FAC1_mantissa+1 - bne round_zero_FACOV + bne round_FAC1_zero_FACOV inc FAC1_mantissa+0 - bne round_zero_FACOV + bne round_FAC1_zero_FACOV // If we are here, it means mantissa is 0; put it to minimum allowed and increment exponent lda #$80 sta FAC1_mantissa+0 inc FAC1_exponent - bne round_zero_FACOV + bne round_FAC1_zero_FACOV // If we are here, it means the exponent wrapped around to $00; put it back to $FF @@ -49,13 +49,13 @@ ROUND: // FALLTROUGH -round_zero_FACOV: +round_FAC1_zero_FACOV: lda #$00 sta FACOV // FALLTROUGH -round_done: +round_FAC1_done: rts From c62f53058e585344179e7877f2e4fa717fd9faea Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 2 Feb 2020 11:04:39 +0100 Subject: [PATCH 32/66] implemented several simple floating point routines --- STATUS.md | 13 ++-- c64/basic/,stubs_math/bbfc.MOVEF.s | 17 ---- .../bbd4.interop => math/bbc7.interop} | 0 c64/basic/math/bbc7.mov_r_FAC1_TMP2.s | 7 ++ .../bbfc.interop => math/bbca.interop} | 0 c64/basic/math/bbca.mov_r_FAC1_TMP1.s | 7 ++ c64/basic/math/bbd0.interop | 3 + c64/basic/math/bbd0.mov_r_FAC1_VAR.s | 20 +++++ c64/basic/math/bbd4.interop | 3 + .../bbd4.mov_r_FAC1_MEM.s} | 11 +-- c64/basic/math/bbfc.interop | 3 + c64/basic/math/bbfc.mov_FAC2_FAC1.s | 7 ++ c64/basic/math/bc0c.mov_r_FAC1_FAC2.s | 2 +- c64/basic/math/mov_FAC1_MEM.s | 77 +++++++++++++++++++ c64/basic/math/mov_FAC2_FAC1.s | 49 ++++++++++++ c64/basic/math/mov_r_FAC1_TMP1.s | 18 +++++ c64/basic/math/mov_r_FAC1_TMP2.s | 18 +++++ 17 files changed, 227 insertions(+), 28 deletions(-) delete mode 100644 c64/basic/,stubs_math/bbfc.MOVEF.s rename c64/basic/{,stubs_math/bbd4.interop => math/bbc7.interop} (100%) create mode 100644 c64/basic/math/bbc7.mov_r_FAC1_TMP2.s rename c64/basic/{,stubs_math/bbfc.interop => math/bbca.interop} (100%) create mode 100644 c64/basic/math/bbca.mov_r_FAC1_TMP1.s create mode 100644 c64/basic/math/bbd0.interop create mode 100644 c64/basic/math/bbd0.mov_r_FAC1_VAR.s create mode 100644 c64/basic/math/bbd4.interop rename c64/basic/{,stubs_math/bbd4.MOVMF2.s => math/bbd4.mov_r_FAC1_MEM.s} (68%) create mode 100644 c64/basic/math/bbfc.interop create mode 100644 c64/basic/math/bbfc.mov_FAC2_FAC1.s create mode 100644 c64/basic/math/mov_FAC1_MEM.s create mode 100644 c64/basic/math/mov_FAC2_FAC1.s create mode 100644 c64/basic/math/mov_r_FAC1_TMP1.s create mode 100644 c64/basic/math/mov_r_FAC1_TMP2.s diff --git a/STATUS.md b/STATUS.md index 9b2d1f73..98646059 100644 --- a/STATUS.md +++ b/STATUS.md @@ -179,7 +179,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | | `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | | `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | -| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `sub_FAC2_FAC1` | +| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B86A` | `add_FAC2_FAC1` | NOT DONE | | @@ -193,11 +193,14 @@ Floating point mathematical routines - not official, but well known and broadly | `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | | `$BB12` | `div_FAC2_FAC1` | NOT DONE | | | `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | -| `$BBD4` | `MOVFM2` | NOT DONE | copy FAC1 to memory location, rounds if asked | -| `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | -| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested | +| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | +| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | +| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | +| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | +| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | +| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | | `$BC0F` | `mov_FAC1_FAC2` | DONE | | -| `$BC1B` | `round_FAC1` | PARTIAL | not tested | +| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | | `$BC2B` | `sgn_FAC1_A` | NOT DONE | | | `$BC39` | `sgn_FAC1` | NOT DONE | | | `$BC58` | `abs_FAC1` | NOT DONE | | diff --git a/c64/basic/,stubs_math/bbfc.MOVEF.s b/c64/basic/,stubs_math/bbfc.MOVEF.s deleted file mode 100644 index b04de5b6..00000000 --- a/c64/basic/,stubs_math/bbfc.MOVEF.s +++ /dev/null @@ -1,17 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - copy FAC2 to FAC1 -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 115 -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -MOVEF: - STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bbd4.interop b/c64/basic/math/bbc7.interop similarity index 100% rename from c64/basic/,stubs_math/bbd4.interop rename to c64/basic/math/bbc7.interop diff --git a/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s new file mode 100644 index 00000000..9fd4c393 --- /dev/null +++ b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_r_FAC1_TMP2 diff --git a/c64/basic/,stubs_math/bbfc.interop b/c64/basic/math/bbca.interop similarity index 100% rename from c64/basic/,stubs_math/bbfc.interop rename to c64/basic/math/bbca.interop diff --git a/c64/basic/math/bbca.mov_r_FAC1_TMP1.s b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s new file mode 100644 index 00000000..1b3ed69c --- /dev/null +++ b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_r_FAC1_TMP1 diff --git a/c64/basic/math/bbd0.interop b/c64/basic/math/bbd0.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbd0.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/bbd0.mov_r_FAC1_VAR.s b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s new file mode 100644 index 00000000..2d34f663 --- /dev/null +++ b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - move FAC1 (rounds) to memory variable +// +// Input: +// - FORPNT ($49/$4A) - variable address +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +mov_r_FAC1_VAR: + + ldy #FORPNT+1 + ldx #FORPNT+0 + + // FALLTROUGH to mov_r_FAC1_MEM diff --git a/c64/basic/math/bbd4.interop b/c64/basic/math/bbd4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbd4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bbd4.MOVMF2.s b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s similarity index 68% rename from c64/basic/,stubs_math/bbd4.MOVMF2.s rename to c64/basic/math/bbd4.mov_r_FAC1_MEM.s index 850adaa5..26f898bd 100644 --- a/c64/basic/,stubs_math/bbd4.MOVMF2.s +++ b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s @@ -3,12 +3,11 @@ // #LAYOUT# * * #IGNORE // -// Math package - copy FAC1 to memory location, rounds if asked +// Math package - copy FAC1 to memory location, do not round // // Input: // - .X - address low byte // - .Y - address high byte -// - $70 - if MSB is set performs rouding // // Output: // - .A - FAC1 exponent @@ -18,7 +17,9 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation +mov_r_FAC1_MEM: + + // Start by rounding FAC1 -MOVFM2: - STUB_IMPLEMENTATION() + jsr round_FAC1 + jmp mov_FAC1_MEM diff --git a/c64/basic/math/bbfc.interop b/c64/basic/math/bbfc.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbfc.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/bbfc.mov_FAC2_FAC1.s b/c64/basic/math/bbfc.mov_FAC2_FAC1.s new file mode 100644 index 00000000..509a911a --- /dev/null +++ b/c64/basic/math/bbfc.mov_FAC2_FAC1.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_FAC2_FAC1 diff --git a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s index 6dd59663..084d7e16 100644 --- a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s +++ b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s @@ -14,7 +14,7 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -movr_FAC1_FAC2: +mov_r_FAC1_FAC2: // First round FAC1 jsr round_FAC1 diff --git a/c64/basic/math/mov_FAC1_MEM.s b/c64/basic/math/mov_FAC1_MEM.s new file mode 100644 index 00000000..9a8621fb --- /dev/null +++ b/c64/basic/math/mov_FAC1_MEM.s @@ -0,0 +1,77 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC1 to memory location, do not round +// +// Input: +// - .X - address low byte +// - .Y - address high byte +// +// Output: +// - .A - FAC1 exponent +// +// See also: +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +mov_FAC1_MEM: + + // Checked in the available documentation: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic + // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 + // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. + // Confirmed by experimenting with original ROM that this is the case here too. + + sty INDEX+1 + stx INDEX+0 + + ldy #$00 + + // Copy exponent + + lda FAC1_exponent + sta (INDEX), y + beq mov_FAC1_MEM_end // for 0 no need to copy anything more + + // Copy first byte of mantissa + + iny + lda FAC2_mantissa+3 + sta (INDEX), y + + // Copy the sign XXX try to optimize this part + + lda FAC1_sign + bne !+ + + lda FAC2_mantissa+3 + and #$7F + sta (INDEX), y +!: + // Copy remaining parts of mantissa + + iny + lda FAC2_mantissa+2 + sta (INDEX), y + + iny + lda FAC2_mantissa+1 + sta (INDEX), y + + iny + lda FAC2_mantissa+0 + sta (INDEX), y + + // Checked, that mov_FAC1_MEM works on real ROM too (at $BBD7), + // and clears FACOV in a similar way as mov_FAC1_FAC2 does (not surprising) + + ldy #$00 + sty FACOV + +mov_FAC1_MEM_end: + + lda FAC1_exponent + rts diff --git a/c64/basic/math/mov_FAC2_FAC1.s b/c64/basic/math/mov_FAC2_FAC1.s new file mode 100644 index 00000000..231c0b91 --- /dev/null +++ b/c64/basic/math/mov_FAC2_FAC1.s @@ -0,0 +1,49 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC2 to FAC1 +// +// Output (found by experimentation): +// - .A - FAC1 exponent +// - .X - always 0 +// +// Preserves: +// - .Y +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +mov_FAC2_FAC1: + + // Copy the mantissa + + lda FAC2_mantissa+3 + sta FAC1_mantissa+3 + lda FAC2_mantissa+2 + sta FAC1_mantissa+2 + lda FAC2_mantissa+1 + sta FAC1_mantissa+1 + lda FAC2_mantissa+0 + sta FAC1_mantissa+0 + + // Copy the sign + + lda FAC2_sign + sta FAC1_sign + + // Copy the exponent + + lda FAC2_exponent + sta FAC1_exponent + + // Clear FACOV + + ldx #$00 + stx FACOV + + rts diff --git a/c64/basic/math/mov_r_FAC1_TMP1.s b/c64/basic/math/mov_r_FAC1_TMP1.s new file mode 100644 index 00000000..7edcf115 --- /dev/null +++ b/c64/basic/math/mov_r_FAC1_TMP1.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - store FAC1 (rounds) in TEMPF1 +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// + +mov_r_FAC1_TMP1: + + ldy #$00 + ldx #$5C + + jmp mov_r_FAC1_MEM diff --git a/c64/basic/math/mov_r_FAC1_TMP2.s b/c64/basic/math/mov_r_FAC1_TMP2.s new file mode 100644 index 00000000..3897d02a --- /dev/null +++ b/c64/basic/math/mov_r_FAC1_TMP2.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - store FAC1 (rounds) in TEMPF2 +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// + +mov_r_FAC1_TMP2: + + ldy #$00 + ldx #$57 + + jmp mov_r_FAC1_MEM From b0d01771145464b3666d47f1f775d9ca48ed89b4 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 3 Feb 2020 21:37:27 +0100 Subject: [PATCH 33/66] added exponent alignment routine, fix for FAC1 normalization --- STATUS.md | 95 +++++------ c64/basic/math/add_align_exponents.s | 169 +++++++++++++++++++ c64/basic/math/b862.add_align_exponent.jmp.s | 8 + c64/basic/math/b862.interop | 3 + c64/basic/math/mov_FAC1_MEM.s | 7 +- c64/basic/math/mov_MEM_FAC1.s | 7 +- c64/basic/math/mov_MEM_FAC2.s | 7 +- c64/basic/math/normal_FAC1.s | 48 +++--- 8 files changed, 259 insertions(+), 85 deletions(-) create mode 100644 c64/basic/math/add_align_exponents.s create mode 100644 c64/basic/math/b862.add_align_exponent.jmp.s create mode 100644 c64/basic/math/b862.interop diff --git a/STATUS.md b/STATUS.md index 98646059..328b8215 100644 --- a/STATUS.md +++ b/STATUS.md @@ -174,53 +174,54 @@ Floating point mathematical routines - not official, but well known and broadly
-| Address | Name | Status | Remarks | -| :-------: | :----------------- | :------: | :------------------------------------------------: | -| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | -| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | -| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | -| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | -| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | -| `$B9EA` | `log_FAC1` | NOT DONE | | -| `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | -| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | -| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | -| `$BAE2` | `mul10_FAC1` | NOT DONE | | -| `$BAFE` | `div10_FAC1_p` | NOT DONE | | -| `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | -| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | -| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | -| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | -| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | -| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | -| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | -| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | -| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | -| `$BC0F` | `mov_FAC1_FAC2` | DONE | | -| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | -| `$BC2B` | `sgn_FAC1_A` | NOT DONE | | -| `$BC39` | `sgn_FAC1` | NOT DONE | | -| `$BC58` | `abs_FAC1` | NOT DONE | | -| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | -| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | -| `$BCCC` | `int_FAC1` | NOT DONE | | -| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | -| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | -| `$BF71` | `sqr_FAC1` | NOT DONE | | -| `$BF74` | `sqr_FAC2` | NOT DONE | | -| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | -| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | -| `$BFB4` | `toggle_sign_FAC1` | DONE | | -| `$BFED` | `exp_FAC1` | NOT DONE | | -| `$E043` | `poly1_FAC1` | NOT DONE | | -| `$E059` | `poly2_FAC1` | NOT DONE | | -| `$E264` | `cos_FAC1` | NOT DONE | | -| `$E26B` | `sin_FAC1` | NOT DONE | | -| `$E2B4` | `tan_FAC1` | NOT DONE | | -| `$E30E` | `atn_FAC1` | NOT DONE | | +| Address | Name | Status | Remarks | +| :-------: | :-------------------- | :------: | :------------------------------------------------: | +| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | +| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | +| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | +| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B862` | `add_align_exponents` | PARTIAL | not tested yet | +| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | +| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | +| `$B9EA` | `log_FAC1` | NOT DONE | | +| `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | +| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | +| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | +| `$BAE2` | `mul10_FAC1` | NOT DONE | | +| `$BAFE` | `div10_FAC1_p` | NOT DONE | | +| `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | +| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | +| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | +| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | +| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | +| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | +| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | +| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | +| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | +| `$BC0F` | `mov_FAC1_FAC2` | DONE | | +| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | +| `$BC2B` | `sgn_FAC1_A` | NOT DONE | | +| `$BC39` | `sgn_FAC1` | NOT DONE | | +| `$BC58` | `abs_FAC1` | NOT DONE | | +| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | +| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | +| `$BCCC` | `int_FAC1` | NOT DONE | | +| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | +| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | +| `$BF71` | `sqr_FAC1` | NOT DONE | | +| `$BF74` | `sqr_FAC2` | NOT DONE | | +| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | +| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | +| `$BFB4` | `toggle_sign_FAC1` | DONE | | +| `$BFED` | `exp_FAC1` | NOT DONE | | +| `$E043` | `poly1_FAC1` | NOT DONE | | +| `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E264` | `cos_FAC1` | NOT DONE | | +| `$E26B` | `sin_FAC1` | NOT DONE | | +| `$E2B4` | `tan_FAC1` | NOT DONE | | +| `$E30E` | `atn_FAC1` | NOT DONE | |
diff --git a/c64/basic/math/add_align_exponents.s b/c64/basic/math/add_align_exponents.s new file mode 100644 index 00000000..3956ed9c --- /dev/null +++ b/c64/basic/math/add_align_exponents.s @@ -0,0 +1,169 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - align FAC1 and FAC2 exponents for addition +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/BASIC-ROM + +// XXX finish and test this + +add_align_exponents: + + // XXX assume here none of the exponents is 0, check if this is true for orignal ROMs + + lda FAC1_exponent + cmp FAC2_exponent + beq add_align_exponents_done // branch if exponents the same + bcs add_align_exponent_FAC2 + + // FALLTROUGH + +add_align_exponent_FAC1: + + // First check the exponent difference + + lda FAC2_exponent + sec + sbc FAC1_exponent + + cmp #$28 + bcs add_align_exponent_FAC1_zero // branch if difference is very high + + cmp #$08 + bcc add_align_exponent_FAC1_bit + + // FALLTROUGH + +add_align_exponent_FAC1_byte: + + // Add 8 to exponent, divide mantissa by 256 + + lda FAC1_exponent + clc + adc #$08 + sta FAC1_exponent + + lda FAC1_mantissa+3 + sta FACOV + lda FAC1_mantissa+2 + sta FAC1_mantissa+3 + lda FAC1_mantissa+1 + sta FAC1_mantissa+2 + lda FAC1_mantissa+0 + sta FAC1_mantissa+1 + lda #$00 + sta FAC1_mantissa+0 + + beq add_align_exponent_FAC1 // branch always - next iteration + +add_align_exponent_FAC1_bit: + + // Increment exponent, divide mantissa by 2 + + inc FAC1_exponent + + clc + ror FAC1_mantissa+0 + ror FAC1_mantissa+1 + ror FAC1_mantissa+2 + ror FAC1_mantissa+3 + ror FACOV + + lda FAC1_exponent + cmp FAC2_exponent + bne add_align_exponent_FAC1_bit // branch if next iteration needed + + rts + +add_align_exponent_FAC1_zero: + + lda #$00 + + sta FAC1_mantissa+0 + sta FAC1_mantissa+1 + sta FAC1_mantissa+2 + sta FAC1_mantissa+3 + sta FACOV + + lda FAC2_exponent + sta FAC1_exponent + + // FALLTROUGH + +add_align_exponents_done: + + rts + + + +add_align_exponent_FAC2: + + // First check the exponent difference, Carry already set here + + lda FAC1_exponent + sbc FAC2_exponent + + cmp #$20 + bcs add_align_exponent_FAC2_zero // branch if difference is very high + + cmp #$08 + bcc add_align_exponent_FAC2_bit + + // FALLTROUGH + +add_align_exponent_FAC2_byte: + + // Add 8 to exponent, divide mantissa by 256 + + lda FAC2_exponent + clc + adc #$08 + sta FAC2_exponent + + lda FAC2_mantissa+2 + sta FAC2_mantissa+3 + lda FAC2_mantissa+1 + sta FAC2_mantissa+2 + lda FAC2_mantissa+0 + sta FAC2_mantissa+1 + lda #$00 + sta FAC2_mantissa+0 + + beq add_align_exponent_FAC2 // branch always - next iteration + +add_align_exponent_FAC2_bit: + + // Increment exponent, divide mantissa by 2 + + inc FAC2_exponent + + clc + ror FAC2_mantissa+0 + ror FAC2_mantissa+1 + ror FAC2_mantissa+2 + ror FAC2_mantissa+3 + + lda FAC1_exponent + cmp FAC2_exponent + bne add_align_exponent_FAC2_bit // branch if next iteration needed + + rts + + +add_align_exponent_FAC2_zero: + + lda #$00 + + sta FAC2_mantissa+0 + sta FAC2_mantissa+1 + sta FAC2_mantissa+2 + sta FAC2_mantissa+3 + + lda FAC1_exponent + sta FAC2_exponent + + rts diff --git a/c64/basic/math/b862.add_align_exponent.jmp.s b/c64/basic/math/b862.add_align_exponent.jmp.s new file mode 100644 index 00000000..bcddf0ba --- /dev/null +++ b/c64/basic/math/b862.add_align_exponent.jmp.s @@ -0,0 +1,8 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + + jmp add_align_exponents diff --git a/c64/basic/math/b862.interop b/c64/basic/math/b862.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/b862.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/mov_FAC1_MEM.s b/c64/basic/math/mov_FAC1_MEM.s index 9a8621fb..84d49903 100644 --- a/c64/basic/math/mov_FAC1_MEM.s +++ b/c64/basic/math/mov_FAC1_MEM.s @@ -19,11 +19,8 @@ mov_FAC1_MEM: - // Checked in the available documentation: - // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic - // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 - // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. - // Confirmed by experimenting with original ROM that this is the case here too. + // Original routines use $22/$23 location for a vector too, see here: + // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics sty INDEX+1 stx INDEX+0 diff --git a/c64/basic/math/mov_MEM_FAC1.s b/c64/basic/math/mov_MEM_FAC1.s index 14ceb648..39296f87 100644 --- a/c64/basic/math/mov_MEM_FAC1.s +++ b/c64/basic/math/mov_MEM_FAC1.s @@ -23,11 +23,8 @@ mov_MEM_FAC1: - // Checked in the available documentation: - // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic - // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 - // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. - // Confirmed by experimenting with original ROM that this is the case here too. + // Original routines use $22/$23 location for a vector too, see here: + // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics sty INDEX+1 sta INDEX+0 diff --git a/c64/basic/math/mov_MEM_FAC2.s b/c64/basic/math/mov_MEM_FAC2.s index 0258c041..8102794d 100644 --- a/c64/basic/math/mov_MEM_FAC2.s +++ b/c64/basic/math/mov_MEM_FAC2.s @@ -26,11 +26,8 @@ mov_MEM_FAC2: - // Checked in the available documentation: - // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic - // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 - // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. - // Confirmed by experimenting with original ROM that this is the case here too. + // Original routines use $22/$23 location for a vector too, see here: + // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics sty INDEX+1 sta INDEX+0 diff --git a/c64/basic/math/normal_FAC1.s b/c64/basic/math/normal_FAC1.s index 0dda7581..5dc96fa5 100644 --- a/c64/basic/math/normal_FAC1.s +++ b/c64/basic/math/normal_FAC1.s @@ -16,30 +16,32 @@ normal_FAC1: lda FAC1_exponent - beq normal_FAC1_end // branch if our float is 0 + beq normal_FAC1_end // branch if our float is 0 - lda FAC1_mantissa+3 - beq normal_FAC1_by_byte // branch if we can move the whole byte + // FALLTROUGH + +normal_FAC1_check_mantissa_byte: + + lda FAC1_mantissa+0 + beq normal_FAC1_by_byte // branch if we can move the whole byte + // FALLTROUGH + +normal_FAC1_check_mantissa_bit: + + lda FAC1_mantissa+0 // XXX optimize for 65CE02? and #$80 - bne normal_FAC1_end // branch if already normalized + bne normal_FAC1_end // branch if already normalized // FALLTROUGH normal_FAC1_by_bit: - // First check the current exponent + // Decrement the exponent - lda FAC1_exponent - cmp #$01 - bne !+ - - // Exponent is 1 - just mark the whole number as 0 and finish - - lda #$00 - sta FAC1_exponent - rts -!: + dec FAC1_exponent + beq normal_FAC1_end // exponent reached 0, nothing more to do + // Multiply the mantissa by 2 clc @@ -49,7 +51,7 @@ normal_FAC1_by_bit: rol FAC1_mantissa+1 rol FAC1_mantissa+0 - bcc normal_FAC1 // branch if next iteration needed + bcc normal_FAC1_check_mantissa_bit // branch if next iteration needed rts normal_FAC1_by_byte: @@ -63,19 +65,19 @@ normal_FAC1_by_byte: lda #$00 !: sta FAC1_exponent - beq normal_FAC1_end // branch if our float reached 0 + beq normal_FAC1_end // branch if our float reached 0 // Now multiply the mantissa by 8 by moving the whole bytes - lda FAC1_mantissa+2 - sta FAC1_mantissa+3 lda FAC1_mantissa+1 - sta FAC1_mantissa+2 - lda FAC1_mantissa+0 + sta FAC1_mantissa+0 + lda FAC1_mantissa+2 sta FAC1_mantissa+1 + lda FAC1_mantissa+3 + sta FAC1_mantissa+2 lda FACOV - sta FAC1_mantissa+0 + sta FAC1_mantissa+3 lda #$00 sta FACOV @@ -87,7 +89,7 @@ normal_FAC1_by_byte: ora FAC1_mantissa+2 ora FAC1_mantissa+3 - bne normal_FAC1 // not 0 - branch to next iteration + bne normal_FAC1_check_mantissa_byte // not 0 - branch to next iteration // Our mantissa reached 0 - mark exponent as 0 and finish From c6e95b938281e73ae9999786964f12405db49186 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 4 Feb 2020 20:27:51 +0100 Subject: [PATCH 34/66] added floating point constants generator --- Makefile | 21 ++-- src/generate_constants.cc | 222 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 src/generate_constants.cc diff --git a/Makefile b/Makefile index d3f98316..ca6fc45f 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) # Generated files -GEN_BASIC = build/,generated/packed_messages.s +GEN_BASIC = build/,generated/packed_messages.s build/,generated/float_constants.s GEN_KERNAL = # List of build directories @@ -70,13 +70,14 @@ DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL) # List of tools -TOOL_COLLECT_DATA = build/tools/collect_data -TOOL_COMPRESS_TEXT = build/tools/compress_text -TOOL_PNGPREPARE = build/tools/pngprepare -TOOL_BUILD_SEGMENT = build/tools/build_segment -TOOL_RELEASE = build/tools/release -TOOL_SIMILARITY = build/tools/similarity -TOOL_ASSEMBLER = assembler/KickAss.jar +TOOL_COLLECT_DATA = build/tools/collect_data +TOOL_COMPRESS_TEXT = build/tools/compress_text +TOOL_GENERATE_CONSTANTS = build/tools/generate_constants +TOOL_PNGPREPARE = build/tools/pngprepare +TOOL_BUILD_SEGMENT = build/tools/build_segment +TOOL_RELEASE = build/tools/release +TOOL_SIMILARITY = build/tools/similarity +TOOL_ASSEMBLER = assembler/KickAss.jar TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS))) @@ -212,6 +213,10 @@ build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT) @mkdir -p build/,generated $(TOOL_COMPRESS_TEXT) > build/,generated/packed_messages.s +build/,generated/float_constants.s: $(TOOL_GENERATE_CONSTANTS) + @mkdir -p build/,generated + $(TOOL_GENERATE_CONSTANTS) -o build/,generated/float_constants.s + .PRECIOUS: build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs: @mkdir -p build/target_$* diff --git a/src/generate_constants.cc b/src/generate_constants.cc new file mode 100644 index 00000000..e0f12044 --- /dev/null +++ b/src/generate_constants.cc @@ -0,0 +1,222 @@ +// +// Utility to generate various floating points constants +// in a Commodore-specific variable format +// + +#include "common.h" + +#include + +#include +#include +#include +#include +#include + +// +// Basic types definition +// + +typedef struct ConstEntry +{ + ConstEntry(const std::string &constName, double constValue) : + constName(constName), + constValue(constValue), + outString(".error \"not generated\"") + { + }; + + const std::string constName; + const double constValue; + + std::string outString; + +} ConstEntry; + +// +// Constants to output +// + +std::vector GLOBAL_constants = +{ + ConstEntry( "PI", M_PI ), + ConstEntry( "HALF", 0.5 ), + ConstEntry( "1", 1.0 ), + ConstEntry( "10", 10.0 ), +}; + +// +// Command line settings +// + +std::string CMD_outFile = "out.s"; + +// +// Common helper functions +// + +void printUsage() +{ + std::cout << "\n" << + "usage: generate_constants [-o ]" << "\n\n"; +} + +void printBanner() +{ + printBannerLineTop(); + std::cout << "// Generating floating point constants" << "\n"; + printBannerLineBottom(); +} + +// +// Top-level functions +// + +void parseCommandLine(int argc, char **argv) +{ + int opt; + + // Retrieve command line options + + while ((opt = getopt(argc, argv, "o:")) != -1) + { + switch(opt) + { + case 'o': CMD_outFile = optarg; break; + default: printUsage(); ERROR(); + } + } +} + +// +// Constants generation +// + +std::string toAssemblerString(const std::string &constName, double constValue) +{ + uint8_t outFloat[5] = { 0 }; + + // Retrieve mantissa nad exponent + + int exponent = -0x80; + double mantissa = frexp(std::abs(constValue), &exponent); + + // Add a bias to exponent + + exponent += 0x80; + + // Check if output format can contain such a number + + if (exponent > 0xFF) + { + ERROR(std::string("const '") + constName + "' abs value too large"); + } + else if (exponent <= 0) + { + ERROR(std::string("const '") + constName + "' abs value too small"); + } + + // Set output constant exponent + + outFloat[0] = exponent; + + // Set output constant mantissa + + for (uint8_t idxByte = 1; idxByte <= 4; idxByte++) + { + for (uint8_t idxBit = 0; idxBit <= 7; idxBit++) + { + outFloat[idxByte] = outFloat[idxByte] << 1; + if (mantissa >= 0.5) + { + outFloat[idxByte]++; + mantissa -= 0.5; + } + + mantissa *= 2; + } + } + + if (outFloat[1] < 0x80) ERROR(std::string("const '") + constName + "' not normalized"); + + // Set output constant sign + + if (constValue >= 0.0) + { + outFloat[1] = outFloat[1] & 0x7F; + } + + // Return the output constant as string for assembler + + char buf[256] = { 0 }; + snprintf(buf, sizeof(buf), "$%02X, $%02X, $%02X, $%02X, $%02X // %22.10f", + outFloat[0], + outFloat[1], + outFloat[2], + outFloat[3], + outFloat[4], + constValue); + + std::string outDef = std::string("\n.macro putConst_") + constName + "()\n{\n\t.byte " + buf + "\n}\n"; + + return outDef; +} + + +void writeConstants() +{ + // Convert constants to assembler strings + + for (auto &entry : GLOBAL_constants) + { + entry.outString = toAssemblerString(entry.constName, entry.constValue); + } + + // Remove old file + + unlink(CMD_outFile.c_str()); + + // Open output file for writing + + std::ofstream outFile(CMD_outFile, std::fstream::out | std::fstream::trunc); + if (!outFile.good()) ERROR(std::string("can't open oputput file '") + CMD_outFile + "'"); + + // Write header + + outFile << "//\n// Generated file - do not edit\n//\n\n"; + + // Write constants + + for (auto &entry : GLOBAL_constants) + { + outFile << entry.outString; + } + + if (!outFile.good()) + { + outFile.close(); + unlink(CMD_outFile.c_str()); + ERROR(std::string("can't write oputput file '") + CMD_outFile + "'"); + } + + // Close the file + + outFile.close(); + + std::cout << std::string("Constants written to: ") + CMD_outFile + "\n\n"; +} + + +// +// Main function +// + +int main(int argc, char **argv) +{ + parseCommandLine(argc, argv); + + printBanner(); + writeConstants(); + + return 0; +} From 98ad2952b1f47973e73c2beaf162399387b656d3 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 4 Feb 2020 21:16:02 +0100 Subject: [PATCH 35/66] added rounding for floating point constants export --- src/generate_constants.cc | 40 +++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/generate_constants.cc b/src/generate_constants.cc index e0f12044..d6a959aa 100644 --- a/src/generate_constants.cc +++ b/src/generate_constants.cc @@ -39,10 +39,21 @@ typedef struct ConstEntry std::vector GLOBAL_constants = { - ConstEntry( "PI", M_PI ), - ConstEntry( "HALF", 0.5 ), - ConstEntry( "1", 1.0 ), - ConstEntry( "10", 10.0 ), + // Constants from: + // - https://www.c64-wiki.com/wiki/BASIC-ROM + // Computes Mapping the Commodore 64, pages 103, 105, 113, 114, 116 + + ConstEntry( "HALF", 0.5 ), + ConstEntry( "MINUS_HALF", -0.5 ), + ConstEntry( "1", 1.0 ), + ConstEntry( "10", 10.0 ), + ConstEntry( "N32768", -32768.0 ), + + ConstEntry( "PI", M_PI ), + ConstEntry( "SQR_2", std::sqrt(2.0) ), + ConstEntry( "1_OVER_SQR_2", 1.0 / std::sqrt(2.0) ), + ConstEntry( "LOG_2", std::log(2.0) ), + ConstEntry( "1_OVER_LOG_2", 1.0 / std::log(2.0) ), }; // @@ -101,6 +112,26 @@ std::string toAssemblerString(const std::string &constName, double constValue) int exponent = -0x80; double mantissa = frexp(std::abs(constValue), &exponent); + // Round the mantissa to output format precission + + const double coeff = 256.0 * 256.0 * 256.0 * 256.0; + + double intPart; + if (modf(mantissa * coeff, &intPart) >= 0.5) + { + mantissa = (intPart + 1.0) / coeff; + } + else + { + mantissa = intPart / coeff; + } + + if (mantissa >= 1.0) + { + mantissa = 0.5; + exponent++; + } + // Add a bias to exponent exponent += 0x80; @@ -137,6 +168,7 @@ std::string toAssemblerString(const std::string &constName, double constValue) } } + if (mantissa > 0.0) ERROR(std::string("const '") + constName + "' export error"); if (outFloat[1] < 0x80) ERROR(std::string("const '") + constName + "' not normalized"); // Set output constant sign From 2305856d63b540d1b3b261d7368d6350c012725a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 4 Feb 2020 22:49:01 +0100 Subject: [PATCH 36/66] added several floating point constants --- Makefile | 1 + STATUS.md | 17 +++++++++++++++ c64/basic/math_consts/aea8.const_PI.s | 13 ++++++++++++ c64/basic/math_consts/aea8.interop | 1 + c64/basic/math_consts/b1a5.const_NEG_32768.s | 13 ++++++++++++ c64/basic/math_consts/b1a5.interop | 1 + c64/basic/math_consts/b9bc.const_ONE.s | 13 ++++++++++++ c64/basic/math_consts/b9bc.interop | 1 + c64/basic/math_consts/b9d6.const_INV_SQR_2.s | 12 +++++++++++ c64/basic/math_consts/b9d6.interop | 1 + c64/basic/math_consts/b9db.const_SQR_2.s | 12 +++++++++++ c64/basic/math_consts/b9db.interop | 1 + c64/basic/math_consts/b9e0.const_NEG_HALF.s | 12 +++++++++++ c64/basic/math_consts/b9e0.interop | 1 + c64/basic/math_consts/b9e5.const_LOG_2.s | 12 +++++++++++ c64/basic/math_consts/b9e5.interop | 1 + c64/basic/math_consts/baf9.const_TEN.s | 13 ++++++++++++ c64/basic/math_consts/baf9.interop | 1 + c64/basic/math_consts/bf11.const_HALF.s | 13 ++++++++++++ c64/basic/math_consts/bf11.interop | 1 + c64/basic/math_consts/bfbf.const_INV_LOG_2.s | 12 +++++++++++ c64/basic/math_consts/bfbf.interop | 1 + c64/basic/math_consts/bfe8.const_ONE.s | 10 +++++++++ c64/basic/math_consts/bfe8.interop | 1 + src/generate_constants.cc | 22 ++++++++++---------- 25 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 c64/basic/math_consts/aea8.const_PI.s create mode 100644 c64/basic/math_consts/aea8.interop create mode 100644 c64/basic/math_consts/b1a5.const_NEG_32768.s create mode 100644 c64/basic/math_consts/b1a5.interop create mode 100644 c64/basic/math_consts/b9bc.const_ONE.s create mode 100644 c64/basic/math_consts/b9bc.interop create mode 100644 c64/basic/math_consts/b9d6.const_INV_SQR_2.s create mode 100644 c64/basic/math_consts/b9d6.interop create mode 100644 c64/basic/math_consts/b9db.const_SQR_2.s create mode 100644 c64/basic/math_consts/b9db.interop create mode 100644 c64/basic/math_consts/b9e0.const_NEG_HALF.s create mode 100644 c64/basic/math_consts/b9e0.interop create mode 100644 c64/basic/math_consts/b9e5.const_LOG_2.s create mode 100644 c64/basic/math_consts/b9e5.interop create mode 100644 c64/basic/math_consts/baf9.const_TEN.s create mode 100644 c64/basic/math_consts/baf9.interop create mode 100644 c64/basic/math_consts/bf11.const_HALF.s create mode 100644 c64/basic/math_consts/bf11.interop create mode 100644 c64/basic/math_consts/bfbf.const_INV_LOG_2.s create mode 100644 c64/basic/math_consts/bfbf.interop create mode 100644 c64/basic/math_consts/bfe8.const_ONE.s create mode 100644 c64/basic/math_consts/bfe8.interop diff --git a/Makefile b/Makefile index ca6fc45f..02103bbd 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \ c64/basic/commands \ c64/basic/init \ c64/basic/math \ + c64/basic/math_consts \ c64/basic/rom_revision SRCDIR_KERNAL = $(SRCDIR_COMMON) \ diff --git a/STATUS.md b/STATUS.md index 328b8215..f9c5439f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -225,6 +225,23 @@ Floating point mathematical routines - not official, but well known and broadly
+In addition to the routines, the following floating-number constants are available at their original locations: + +| Address | Name | Status | Remarks | +| :-------: | :-------------------- | :------: | :------------------------------------------------: | +| `$AEA8` | `const_PI` | DONE | π | +| `$B1A5` | `const_NEG_32768` | DONE | -32768 | +| `$B9BC` | `const_ONE` | DONE | 1.0 | +| `$B9D6` | `const_INV_SQR_2` | DONE | 1 / sqr(2) | +| `$B9DB` | `const_SQR_2` | DONE | sqr(2) | +| `$B9E0` | `const_NEG_HALF` | DONE | -0.5 | +| `$B9E5` | `const_LOG_2` | DONE | log_e(2) | +| `$BAF9` | `const_TEN` | DONE | 10.0 | +| `$BF11` | `const_HALF` | DONE | 0.5 | +| `$BFBF` | `const_INV_LOG_2` | DONE | 1 / log_e(2) | +| `$BFE8` | `const_ONE` duplicate | DONE | 1.0 | + + ### Other unofficial BASIC routines/locations Not all of them - only these we want to have implemented. diff --git a/c64/basic/math_consts/aea8.const_PI.s b/c64/basic/math_consts/aea8.const_PI.s new file mode 100644 index 00000000..c5d79808 --- /dev/null +++ b/c64/basic/math_consts/aea8.const_PI.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - Computes Mapping the Commodore 64, page 103 +// + +const_PI: + + put_const_PI() diff --git a/c64/basic/math_consts/aea8.interop b/c64/basic/math_consts/aea8.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/aea8.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b1a5.const_NEG_32768.s b/c64/basic/math_consts/b1a5.const_NEG_32768.s new file mode 100644 index 00000000..2319be90 --- /dev/null +++ b/c64/basic/math_consts/b1a5.const_NEG_32768.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - Computes Mapping the Commodore 64, page 105 +// + +CONST_NEG_32768: + + put_const_NEG_32768() diff --git a/c64/basic/math_consts/b1a5.interop b/c64/basic/math_consts/b1a5.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b1a5.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b9bc.const_ONE.s b/c64/basic/math_consts/b9bc.const_ONE.s new file mode 100644 index 00000000..63e4eab9 --- /dev/null +++ b/c64/basic/math_consts/b9bc.const_ONE.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - Computes Mapping the Commodore 64, page 113 +// + +const_ONE: + + put_const_ONE() diff --git a/c64/basic/math_consts/b9bc.interop b/c64/basic/math_consts/b9bc.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b9bc.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b9d6.const_INV_SQR_2.s b/c64/basic/math_consts/b9d6.const_INV_SQR_2.s new file mode 100644 index 00000000..2bd0db76 --- /dev/null +++ b/c64/basic/math_consts/b9d6.const_INV_SQR_2.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +const_INV_SQR_2: + + put_const_INV_SQR_2() diff --git a/c64/basic/math_consts/b9d6.interop b/c64/basic/math_consts/b9d6.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b9d6.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b9db.const_SQR_2.s b/c64/basic/math_consts/b9db.const_SQR_2.s new file mode 100644 index 00000000..7a4d3def --- /dev/null +++ b/c64/basic/math_consts/b9db.const_SQR_2.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +const_SQR_2: + + put_const_SQR_2() diff --git a/c64/basic/math_consts/b9db.interop b/c64/basic/math_consts/b9db.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b9db.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b9e0.const_NEG_HALF.s b/c64/basic/math_consts/b9e0.const_NEG_HALF.s new file mode 100644 index 00000000..08ad27d2 --- /dev/null +++ b/c64/basic/math_consts/b9e0.const_NEG_HALF.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +const_NEG_HALF: + + put_const_NEG_HALF() diff --git a/c64/basic/math_consts/b9e0.interop b/c64/basic/math_consts/b9e0.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b9e0.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/b9e5.const_LOG_2.s b/c64/basic/math_consts/b9e5.const_LOG_2.s new file mode 100644 index 00000000..1d9286a7 --- /dev/null +++ b/c64/basic/math_consts/b9e5.const_LOG_2.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +const_LOG_2: + + put_const_LOG_2() diff --git a/c64/basic/math_consts/b9e5.interop b/c64/basic/math_consts/b9e5.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/b9e5.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/baf9.const_TEN.s b/c64/basic/math_consts/baf9.const_TEN.s new file mode 100644 index 00000000..65c8b61b --- /dev/null +++ b/c64/basic/math_consts/baf9.const_TEN.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - Computes Mapping the Commodore 64, page 114 +// + +const_TEN: + + put_const_TEN() diff --git a/c64/basic/math_consts/baf9.interop b/c64/basic/math_consts/baf9.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/baf9.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/bf11.const_HALF.s b/c64/basic/math_consts/bf11.const_HALF.s new file mode 100644 index 00000000..8574ee8b --- /dev/null +++ b/c64/basic/math_consts/bf11.const_HALF.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - Computes Mapping the Commodore 64, page 116 +// + +const_HALF: + + put_const_HALF() diff --git a/c64/basic/math_consts/bf11.interop b/c64/basic/math_consts/bf11.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/bf11.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/bfbf.const_INV_LOG_2.s b/c64/basic/math_consts/bfbf.const_INV_LOG_2.s new file mode 100644 index 00000000..78cf4362 --- /dev/null +++ b/c64/basic/math_consts/bfbf.const_INV_LOG_2.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +const_INV_LOG_2: + + put_const_INV_LOG_2() diff --git a/c64/basic/math_consts/bfbf.interop b/c64/basic/math_consts/bfbf.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/bfbf.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/bfe8.const_ONE.s b/c64/basic/math_consts/bfe8.const_ONE.s new file mode 100644 index 00000000..1f7dab4c --- /dev/null +++ b/c64/basic/math_consts/bfe8.const_ONE.s @@ -0,0 +1,10 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + + put_const_ONE() // duplicated constant - no label diff --git a/c64/basic/math_consts/bfe8.interop b/c64/basic/math_consts/bfe8.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/bfe8.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/src/generate_constants.cc b/src/generate_constants.cc index d6a959aa..b9a11a45 100644 --- a/src/generate_constants.cc +++ b/src/generate_constants.cc @@ -43,17 +43,17 @@ std::vector GLOBAL_constants = // - https://www.c64-wiki.com/wiki/BASIC-ROM // Computes Mapping the Commodore 64, pages 103, 105, 113, 114, 116 - ConstEntry( "HALF", 0.5 ), - ConstEntry( "MINUS_HALF", -0.5 ), - ConstEntry( "1", 1.0 ), - ConstEntry( "10", 10.0 ), - ConstEntry( "N32768", -32768.0 ), + ConstEntry( "HALF", 0.5 ), + ConstEntry( "NEG_HALF", -0.5 ), + ConstEntry( "ONE", 1.0 ), + ConstEntry( "TEN", 10.0 ), + ConstEntry( "NEG_32768", -32768.0 ), - ConstEntry( "PI", M_PI ), - ConstEntry( "SQR_2", std::sqrt(2.0) ), - ConstEntry( "1_OVER_SQR_2", 1.0 / std::sqrt(2.0) ), - ConstEntry( "LOG_2", std::log(2.0) ), - ConstEntry( "1_OVER_LOG_2", 1.0 / std::log(2.0) ), + ConstEntry( "PI", M_PI ), + ConstEntry( "SQR_2", std::sqrt(2.0) ), + ConstEntry( "INV_SQR_2", 1.0 / std::sqrt(2.0) ), + ConstEntry( "LOG_2", std::log(2.0) ), + ConstEntry( "INV_LOG_2", 1.0 / std::log(2.0) ), }; // @@ -189,7 +189,7 @@ std::string toAssemblerString(const std::string &constName, double constValue) outFloat[4], constValue); - std::string outDef = std::string("\n.macro putConst_") + constName + "()\n{\n\t.byte " + buf + "\n}\n"; + std::string outDef = std::string("\n.macro put_const_") + constName + "()\n{\n\t.byte " + buf + "\n}\n"; return outDef; } From d5f6f1924ef78bd12afc74c742d8f7dd450bcbb1 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 5 Feb 2020 17:31:33 +0100 Subject: [PATCH 37/66] renamed 'src' to 'tools' --- Makefile | 12 ++++++------ {src => tools}/build_segment.cc | 0 {src => tools}/collect_data.c | 0 {src => tools}/common.h | 0 {src => tools}/compress_text.c | 0 {src => tools}/generate_constants.cc | 0 {src => tools}/outdated/basic005.c | 0 {src => tools}/outdated/prepare_startup.c | 0 {src => tools}/outdated/preprocess.c | 0 {src => tools}/pngprepare.c | 0 {src => tools}/release.cc | 0 {src => tools}/similarity.c | 0 12 files changed, 6 insertions(+), 6 deletions(-) rename {src => tools}/build_segment.cc (100%) rename {src => tools}/collect_data.c (100%) rename {src => tools}/common.h (100%) rename {src => tools}/compress_text.c (100%) rename {src => tools}/generate_constants.cc (100%) rename {src => tools}/outdated/basic005.c (100%) rename {src => tools}/outdated/prepare_startup.c (100%) rename {src => tools}/outdated/preprocess.c (100%) rename {src => tools}/pngprepare.c (100%) rename {src => tools}/release.cc (100%) rename {src => tools}/similarity.c (100%) diff --git a/Makefile b/Makefile index 02103bbd..b80ef23f 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \ SRC_BASIC = $(foreach dir,$(SRCDIR_BASIC),$(wildcard $(dir)/*.s)) SRC_KERNAL = $(foreach dir,$(SRCDIR_KERNAL),$(wildcard $(dir)/*.s)) -SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) +SRC_TOOLS = $(wildcard tools/*.c,tools/*.cc) # Generated files @@ -80,7 +80,7 @@ TOOL_RELEASE = build/tools/release TOOL_SIMILARITY = build/tools/similarity TOOL_ASSEMBLER = assembler/KickAss.jar -TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS))) +TOOLS_LIST = $(pathsubst tools/%,build/tools/%,$(basename $(SRC_TOOLS))) # List of targets @@ -131,19 +131,19 @@ updatebin: # Rules - tools -$(TOOL_PNGPREPARE): src/pngprepare.c +$(TOOL_PNGPREPARE): tools/pngprepare.c @mkdir -p build/tools $(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lpng -$(TOOL_COMPRESS_TEXT): src/compress_text.c +$(TOOL_COMPRESS_TEXT): tools/compress_text.c @mkdir -p build/tools $(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lm -build/tools/%: src/%.c +build/tools/%: tools/%.c @mkdir -p build/tools $(CC) -O2 -Wall -o $@ $< -build/tools/%: src/%.cc src/common.h +build/tools/%: tools/%.cc tools/common.h @mkdir -p build/tools $(CXX) -O2 -Wall -o $@ $< diff --git a/src/build_segment.cc b/tools/build_segment.cc similarity index 100% rename from src/build_segment.cc rename to tools/build_segment.cc diff --git a/src/collect_data.c b/tools/collect_data.c similarity index 100% rename from src/collect_data.c rename to tools/collect_data.c diff --git a/src/common.h b/tools/common.h similarity index 100% rename from src/common.h rename to tools/common.h diff --git a/src/compress_text.c b/tools/compress_text.c similarity index 100% rename from src/compress_text.c rename to tools/compress_text.c diff --git a/src/generate_constants.cc b/tools/generate_constants.cc similarity index 100% rename from src/generate_constants.cc rename to tools/generate_constants.cc diff --git a/src/outdated/basic005.c b/tools/outdated/basic005.c similarity index 100% rename from src/outdated/basic005.c rename to tools/outdated/basic005.c diff --git a/src/outdated/prepare_startup.c b/tools/outdated/prepare_startup.c similarity index 100% rename from src/outdated/prepare_startup.c rename to tools/outdated/prepare_startup.c diff --git a/src/outdated/preprocess.c b/tools/outdated/preprocess.c similarity index 100% rename from src/outdated/preprocess.c rename to tools/outdated/preprocess.c diff --git a/src/pngprepare.c b/tools/pngprepare.c similarity index 100% rename from src/pngprepare.c rename to tools/pngprepare.c diff --git a/src/release.cc b/tools/release.cc similarity index 100% rename from src/release.cc rename to tools/release.cc diff --git a/src/similarity.c b/tools/similarity.c similarity index 100% rename from src/similarity.c rename to tools/similarity.c From 377b217aec2951f812e08a38a0d765c4333702fa Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 5 Feb 2020 19:16:10 +0100 Subject: [PATCH 38/66] added more floating point stubs --- STATUS.md | 112 ++++++++++-------- .../,stubs_math/a9c4.convert_FAC1_to_INT.s | 21 ++++ c64/basic/,stubs_math/a9c4.interop | 3 + c64/basic/,stubs_math/aabc.interop | 3 + c64/basic/,stubs_math/aabc.print_FAC1.s | 17 +++ c64/basic/,stubs_math/af7b.compute_TI.s | 16 +++ c64/basic/,stubs_math/af7b.interop | 3 + c64/basic/,stubs_math/af7e.interop | 3 + c64/basic/,stubs_math/af7e.math_stub.s | 14 +++ c64/basic/,stubs_math/af87.interop | 3 + c64/basic/,stubs_math/af87.math_stub.s | 14 +++ c64/basic/,stubs_math/af9a.compute_ST.s | 16 +++ c64/basic/,stubs_math/af9a.interop | 3 + .../,stubs_math/b3a2.convert_Y_to_FAC1.s | 15 +++ c64/basic/,stubs_math/b3a2.interop | 3 + .../,stubs_math/b794.convert_A_to_FAC1.s | 12 ++ c64/basic/,stubs_math/b794.interop | 3 + .../,stubs_math/b7f7.convert_FAC1_to_ADDR.s | 19 +++ c64/basic/,stubs_math/b7f7.interop | 3 + c64/basic/,stubs_math/b849.add_HALF_FAC1.s | 15 +++ c64/basic/,stubs_math/b849.interop | 3 + c64/basic/,stubs_math/b947.interop | 3 + .../,stubs_math/b947.inv_FAC1_mantissa.s | 19 +++ c64/basic/,stubs_math/b983.MULSHF.s | 17 +++ c64/basic/,stubs_math/b983.interop | 3 + c64/basic/,stubs_math/ba59.MLTPLY.s | 17 +++ c64/basic/,stubs_math/ba59.interop | 3 + .../,stubs_math/bc3c.convert_A_to_FAC1.s | 13 ++ c64/basic/,stubs_math/bc3c.interop | 3 + .../,stubs_math/bc44.convert_i16_to_FAC1.s | 12 ++ c64/basic/,stubs_math/bc44.interop | 3 + c64/basic/,stubs_math/bd7e.FINLOG.s | 17 +++ c64/basic/,stubs_math/bd7e.interop | 3 + 33 files changed, 366 insertions(+), 48 deletions(-) create mode 100644 c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s create mode 100644 c64/basic/,stubs_math/a9c4.interop create mode 100644 c64/basic/,stubs_math/aabc.interop create mode 100644 c64/basic/,stubs_math/aabc.print_FAC1.s create mode 100644 c64/basic/,stubs_math/af7b.compute_TI.s create mode 100644 c64/basic/,stubs_math/af7b.interop create mode 100644 c64/basic/,stubs_math/af7e.interop create mode 100644 c64/basic/,stubs_math/af7e.math_stub.s create mode 100644 c64/basic/,stubs_math/af87.interop create mode 100644 c64/basic/,stubs_math/af87.math_stub.s create mode 100644 c64/basic/,stubs_math/af9a.compute_ST.s create mode 100644 c64/basic/,stubs_math/af9a.interop create mode 100644 c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s create mode 100644 c64/basic/,stubs_math/b3a2.interop create mode 100644 c64/basic/,stubs_math/b794.convert_A_to_FAC1.s create mode 100644 c64/basic/,stubs_math/b794.interop create mode 100644 c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s create mode 100644 c64/basic/,stubs_math/b7f7.interop create mode 100644 c64/basic/,stubs_math/b849.add_HALF_FAC1.s create mode 100644 c64/basic/,stubs_math/b849.interop create mode 100644 c64/basic/,stubs_math/b947.interop create mode 100644 c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s create mode 100644 c64/basic/,stubs_math/b983.MULSHF.s create mode 100644 c64/basic/,stubs_math/b983.interop create mode 100644 c64/basic/,stubs_math/ba59.MLTPLY.s create mode 100644 c64/basic/,stubs_math/ba59.interop create mode 100644 c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s create mode 100644 c64/basic/,stubs_math/bc3c.interop create mode 100644 c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s create mode 100644 c64/basic/,stubs_math/bc44.interop create mode 100644 c64/basic/,stubs_math/bd7e.FINLOG.s create mode 100644 c64/basic/,stubs_math/bd7e.interop diff --git a/STATUS.md b/STATUS.md index f9c5439f..33459a52 100644 --- a/STATUS.md +++ b/STATUS.md @@ -174,54 +174,70 @@ Floating point mathematical routines - not official, but well known and broadly
-| Address | Name | Status | Remarks | -| :-------: | :-------------------- | :------: | :------------------------------------------------: | -| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | -| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | -| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | -| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B862` | `add_align_exponents` | PARTIAL | not tested yet | -| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | -| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | -| `$B9EA` | `log_FAC1` | NOT DONE | | -| `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | -| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | -| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | -| `$BAE2` | `mul10_FAC1` | NOT DONE | | -| `$BAFE` | `div10_FAC1_p` | NOT DONE | | -| `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | -| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | -| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | -| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | -| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | -| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | -| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | -| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | -| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | -| `$BC0F` | `mov_FAC1_FAC2` | DONE | | -| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | -| `$BC2B` | `sgn_FAC1_A` | NOT DONE | | -| `$BC39` | `sgn_FAC1` | NOT DONE | | -| `$BC58` | `abs_FAC1` | NOT DONE | | -| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | -| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | -| `$BCCC` | `int_FAC1` | NOT DONE | | -| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | -| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | -| `$BF71` | `sqr_FAC1` | NOT DONE | | -| `$BF74` | `sqr_FAC2` | NOT DONE | | -| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | -| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | -| `$BFB4` | `toggle_sign_FAC1` | DONE | | -| `$BFED` | `exp_FAC1` | NOT DONE | | -| `$E043` | `poly1_FAC1` | NOT DONE | | -| `$E059` | `poly2_FAC1` | NOT DONE | | -| `$E264` | `cos_FAC1` | NOT DONE | | -| `$E26B` | `sin_FAC1` | NOT DONE | | -| `$E2B4` | `tan_FAC1` | NOT DONE | | -| `$E30E` | `atn_FAC1` | NOT DONE | | +| Address | Name | Status | Remarks | +| :-------: | :--------------------- | :------: | :------------------------------------------------: | +| `$A9C4` | `convert_FAC1_to_INT` | NOT DONE | | +| `$AABC` | `print_FAC1` | NOT DONE | | +| `$AF7B` | `compute_TI` | NOT DONE | | +| `$AF7E` | not named yet | NOT DONE | | +| `$AF87` | not named yet | NOT DONE | | +| `$AF9A` | `compute_ST` | NOT DONE | | +| `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | +| `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | +| `$B3A2` | `convert_Y_to_FAC1` | NOT DONE | | +| `$B794` | `convert_A_to_FAC1` | NOT DONE | | +| `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | +| `$B7F7` | `convert_FAC1_to_ADDR` | NOT DONE | | +| `$B849` | `add_HALF_FAC1` | NOT DONE | | +| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B862` | `add_align_exponents` | PARTIAL | not tested yet | +| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | +| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | +| `$B947` | `inv_FAC1_mantissa` | NOT DONE | | +| `$B983` | `MULSHF` | NOT DONE | | +| `$B9EA` | `log_FAC1` | NOT DONE | | +| `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | +| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | +| `$BA59` | `MLTPLY` | NOT DONE | | +| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | +| `$BAE2` | `mul10_FAC1` | NOT DONE | | +| `$BAFE` | `div10_FAC1_p` | NOT DONE | | +| `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | +| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | +| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | +| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | +| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | +| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | +| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | +| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | +| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | +| `$BC0F` | `mov_FAC1_FAC2` | DONE | | +| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | +| `$BC2B` | `sgn_FAC1_A` | NOT DONE | | +| `$BC39` | `sgn_FAC1` | NOT DONE | | +| `$BC3C` | `convert_A_to_FAC1` | NOT DONE | | +| `$BC44` | `convert_i16_to_FAC1` | NOT DONE | | +| `$BC58` | `abs_FAC1` | NOT DONE | | +| `$BC5B` | `FCOMP` | NOT DONE | compare FAC1 with RAM location | +| `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | +| `$BCCC` | `int_FAC1` | NOT DONE | | +| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | +| `$BD7E` | `FINLOG` | NOT DONE | | +| `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | +| `$BF71` | `sqr_FAC1` | NOT DONE | | +| `$BF74` | `sqr_FAC2` | NOT DONE | | +| `$BF78` | `FPWR` | NOT DONE | set FAC1 as RAM raised to the power of FAC1 | +| `$BF7B` | `FPWRT` | NOT DONE | set FAC1 as FAC2 raised to the power of FAC1 | +| `$BFB4` | `toggle_sign_FAC1` | DONE | | +| `$BFED` | `exp_FAC1` | NOT DONE | | +| `$E043` | `poly1_FAC1` | NOT DONE | | +| `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E264` | `cos_FAC1` | NOT DONE | | +| `$E26B` | `sin_FAC1` | NOT DONE | | +| `$E2B4` | `tan_FAC1` | NOT DONE | | +| `$E30E` | `atn_FAC1` | NOT DONE | |
diff --git a/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s b/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s new file mode 100644 index 00000000..70e6a741 --- /dev/null +++ b/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - subtract FAC1 to integer in memory +// +// Output: +// - integer pointed by $49/$4A +// +// See also: +// - https://sta.c64.org/cbm64basconv.html +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +// XXX implement, test + + +convert_FAC1_to_INT: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/a9c4.interop b/c64/basic/,stubs_math/a9c4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/a9c4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/aabc.interop b/c64/basic/,stubs_math/aabc.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/aabc.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/aabc.print_FAC1.s b/c64/basic/,stubs_math/aabc.print_FAC1.s new file mode 100644 index 00000000..8bcd6a54 --- /dev/null +++ b/c64/basic/,stubs_math/aabc.print_FAC1.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - print FAC1 value +// +// See also: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +// XXX implement, test + + +print_FAC1: + + STUB_IMPLEMENTATION() \ No newline at end of file diff --git a/c64/basic/,stubs_math/af7b.compute_TI.s b/c64/basic/,stubs_math/af7b.compute_TI.s new file mode 100644 index 00000000..835cc59a --- /dev/null +++ b/c64/basic/,stubs_math/af7b.compute_TI.s @@ -0,0 +1,16 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - compute TI value +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +// XXX implement, test + +compute_TI: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/af7b.interop b/c64/basic/,stubs_math/af7b.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/af7b.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/af7e.interop b/c64/basic/,stubs_math/af7e.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/af7e.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/af7e.math_stub.s b/c64/basic/,stubs_math/af7e.math_stub.s new file mode 100644 index 00000000..40a32304 --- /dev/null +++ b/c64/basic/,stubs_math/af7e.math_stub.s @@ -0,0 +1,14 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - sets mantissa to 00yyxxaa +// +// See also: +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX add name, label, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/af87.interop b/c64/basic/,stubs_math/af87.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/af87.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/af87.math_stub.s b/c64/basic/,stubs_math/af87.math_stub.s new file mode 100644 index 00000000..fc4fae09 --- /dev/null +++ b/c64/basic/,stubs_math/af87.math_stub.s @@ -0,0 +1,14 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - set rest of FAC1 and JMP to $b8d2 +// +// See also: +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX add name, label, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/af9a.compute_ST.s b/c64/basic/,stubs_math/af9a.compute_ST.s new file mode 100644 index 00000000..dca181aa --- /dev/null +++ b/c64/basic/,stubs_math/af9a.compute_ST.s @@ -0,0 +1,16 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - compute ST value +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +// XXX implement, test + +compute_ST: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/af9a.interop b/c64/basic/,stubs_math/af9a.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/af9a.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s b/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s new file mode 100644 index 00000000..49df4eb6 --- /dev/null +++ b/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s @@ -0,0 +1,15 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// +// XXX add name, label, documentation, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b3a2.interop b/c64/basic/,stubs_math/b3a2.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b3a2.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s b/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s new file mode 100644 index 00000000..8a91c04d --- /dev/null +++ b/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// - https://sta.c64.org/cbm64basconv.html +// +// XXX add name, label, documentation, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b794.interop b/c64/basic/,stubs_math/b794.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b794.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s b/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s new file mode 100644 index 00000000..eaeee7fc --- /dev/null +++ b/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s @@ -0,0 +1,19 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - subtract FAC1 to memory address at $14/$15 and Y/A +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://sta.c64.org/cbm64basconv.html +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +// XXX implement, test + + +convert_FAC1_to_ADDR: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b7f7.interop b/c64/basic/,stubs_math/b7f7.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b7f7.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b849.add_HALF_FAC1.s b/c64/basic/,stubs_math/b849.add_HALF_FAC1.s new file mode 100644 index 00000000..38f14bc2 --- /dev/null +++ b/c64/basic/,stubs_math/b849.add_HALF_FAC1.s @@ -0,0 +1,15 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add 0.5 to FAC1 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 + +// XXX implement + +add_HALF_FAC1: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b849.interop b/c64/basic/,stubs_math/b849.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b849.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b947.interop b/c64/basic/,stubs_math/b947.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b947.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s b/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s new file mode 100644 index 00000000..aae0f0b2 --- /dev/null +++ b/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s @@ -0,0 +1,19 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - invert FAC1 mantissa +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// + +// XXX implement, test + + +inv_FAC1_mantissa: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b983.MULSHF.s b/c64/basic/,stubs_math/b983.MULSHF.s new file mode 100644 index 00000000..37a4fc00 --- /dev/null +++ b/c64/basic/,stubs_math/b983.MULSHF.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - SHIFT routine +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// + +// XXX implement, test + + +MULSHF: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b983.interop b/c64/basic/,stubs_math/b983.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/b983.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/ba59.MLTPLY.s b/c64/basic/,stubs_math/ba59.MLTPLY.s new file mode 100644 index 00000000..369eab72 --- /dev/null +++ b/c64/basic/,stubs_math/ba59.MLTPLY.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add a mantissa byte of FAC2 to FAC1, do it .A times +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// + +// XXX implement, test + + +MULTPLY: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba59.interop b/c64/basic/,stubs_math/ba59.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/ba59.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s b/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s new file mode 100644 index 00000000..7b5c3cc9 --- /dev/null +++ b/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s @@ -0,0 +1,13 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// - https://codebase64.org/doku.php?id=base:asm_include_file_for_basic_routines +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// +// XXX add name, label, documentation, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc3c.interop b/c64/basic/,stubs_math/bc3c.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc3c.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s b/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s new file mode 100644 index 00000000..9555a39f --- /dev/null +++ b/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// +// XXX add name, label, documentation, implement, test + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bc44.interop b/c64/basic/,stubs_math/bc44.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bc44.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bd7e.FINLOG.s b/c64/basic/,stubs_math/bd7e.FINLOG.s new file mode 100644 index 00000000..65a18e9a --- /dev/null +++ b/c64/basic/,stubs_math/bd7e.FINLOG.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add an ASCII digit that has been converted to a signed integer to FAC1 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 +// + +// XXX implement, test + + +FINLOG: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bd7e.interop b/c64/basic/,stubs_math/bd7e.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/,stubs_math/bd7e.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example From 9b94f30f98a320bdf37ff94172628f5e4573dea1 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 5 Feb 2020 19:37:45 +0100 Subject: [PATCH 39/66] some more floating point constants --- STATUS.md | 31 +++++++++++--------- c64/basic/math_consts/e2e0.const_HALF_PI.s | 12 ++++++++ c64/basic/math_consts/e2e0.interop | 1 + c64/basic/math_consts/e2e5.const_DOUBLE_PI.s | 12 ++++++++ c64/basic/math_consts/e2e5.interop | 1 + c64/basic/math_consts/e2ea.const_QUARTER.s | 12 ++++++++ c64/basic/math_consts/e2ea.interop | 1 + c64/basic/math_consts/e309.const_DOUBLE_PI.s | 10 +++++++ c64/basic/math_consts/e309.interop | 1 + tools/generate_constants.cc | 3 ++ 10 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 c64/basic/math_consts/e2e0.const_HALF_PI.s create mode 100644 c64/basic/math_consts/e2e0.interop create mode 100644 c64/basic/math_consts/e2e5.const_DOUBLE_PI.s create mode 100644 c64/basic/math_consts/e2e5.interop create mode 100644 c64/basic/math_consts/e2ea.const_QUARTER.s create mode 100644 c64/basic/math_consts/e2ea.interop create mode 100644 c64/basic/math_consts/e309.const_DOUBLE_PI.s create mode 100644 c64/basic/math_consts/e309.interop diff --git a/STATUS.md b/STATUS.md index 33459a52..ddd0274d 100644 --- a/STATUS.md +++ b/STATUS.md @@ -243,20 +243,23 @@ Floating point mathematical routines - not official, but well known and broadly In addition to the routines, the following floating-number constants are available at their original locations: -| Address | Name | Status | Remarks | -| :-------: | :-------------------- | :------: | :------------------------------------------------: | -| `$AEA8` | `const_PI` | DONE | π | -| `$B1A5` | `const_NEG_32768` | DONE | -32768 | -| `$B9BC` | `const_ONE` | DONE | 1.0 | -| `$B9D6` | `const_INV_SQR_2` | DONE | 1 / sqr(2) | -| `$B9DB` | `const_SQR_2` | DONE | sqr(2) | -| `$B9E0` | `const_NEG_HALF` | DONE | -0.5 | -| `$B9E5` | `const_LOG_2` | DONE | log_e(2) | -| `$BAF9` | `const_TEN` | DONE | 10.0 | -| `$BF11` | `const_HALF` | DONE | 0.5 | -| `$BFBF` | `const_INV_LOG_2` | DONE | 1 / log_e(2) | -| `$BFE8` | `const_ONE` duplicate | DONE | 1.0 | - +| Address | Name | Status | Remarks | +| :-------: | :-------------------------- | :------: | :-------------------------------------------: | +| `$AEA8` | `const_PI` | DONE | π | +| `$B1A5` | `const_NEG_32768` | DONE | -32768 | +| `$B9BC` | `const_ONE` | DONE | 1.0 | +| `$B9D6` | `const_INV_SQR_2` | DONE | 1.0 / sqr(2.0) | +| `$B9DB` | `const_SQR_2` | DONE | sqr(2.0) | +| `$B9E0` | `const_NEG_HALF` | DONE | -0.5 | +| `$B9E5` | `const_LOG_2` | DONE | log_e(2.0) | +| `$BAF9` | `const_TEN` | DONE | 10.0 | +| `$BF11` | `const_HALF` | DONE | 0.5 | +| `$BFBF` | `const_INV_LOG_2` | DONE | 1.0 / log_e(2.0) | +| `$BFE8` | `const_ONE` duplicate | DONE | 1.0 | +| `$E2E0` | `const_HALF_PI` | DONE | PI / 2.0 | +| `$E2E5` | `const_DOUBLE_PI` | DONE | PI * 2.0 | +| `$E2EA` | `const_QUARTER` | DONE | 0.25 | +| `$E309` | `const_DOUBLE_PI` duplicate | DONE | PI * 2.0 | ### Other unofficial BASIC routines/locations diff --git a/c64/basic/math_consts/e2e0.const_HALF_PI.s b/c64/basic/math_consts/e2e0.const_HALF_PI.s new file mode 100644 index 00000000..a75efb68 --- /dev/null +++ b/c64/basic/math_consts/e2e0.const_HALF_PI.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +const_HALF_PI: + + put_const_HALF_PI() diff --git a/c64/basic/math_consts/e2e0.interop b/c64/basic/math_consts/e2e0.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/e2e0.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/e2e5.const_DOUBLE_PI.s b/c64/basic/math_consts/e2e5.const_DOUBLE_PI.s new file mode 100644 index 00000000..f8728ef7 --- /dev/null +++ b/c64/basic/math_consts/e2e5.const_DOUBLE_PI.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +const_DOUBLE_PI: + + put_const_DOUBLE_PI() diff --git a/c64/basic/math_consts/e2e5.interop b/c64/basic/math_consts/e2e5.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/e2e5.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/e2ea.const_QUARTER.s b/c64/basic/math_consts/e2ea.const_QUARTER.s new file mode 100644 index 00000000..77962d8a --- /dev/null +++ b/c64/basic/math_consts/e2ea.const_QUARTER.s @@ -0,0 +1,12 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +const_QUARTER: + + put_const_QUARTER() \ No newline at end of file diff --git a/c64/basic/math_consts/e2ea.interop b/c64/basic/math_consts/e2ea.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/e2ea.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/c64/basic/math_consts/e309.const_DOUBLE_PI.s b/c64/basic/math_consts/e309.const_DOUBLE_PI.s new file mode 100644 index 00000000..33a01f1b --- /dev/null +++ b/c64/basic/math_consts/e309.const_DOUBLE_PI.s @@ -0,0 +1,10 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - a constant, for documentation see: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + + put_const_DOUBLE_PI() // duplicated constant - no label diff --git a/c64/basic/math_consts/e309.interop b/c64/basic/math_consts/e309.interop new file mode 100644 index 00000000..cdf8d0e7 --- /dev/null +++ b/c64/basic/math_consts/e309.interop @@ -0,0 +1 @@ +A well-known floating-point constant, has to be at the same place or we risk hard to debug improper calculation results. diff --git a/tools/generate_constants.cc b/tools/generate_constants.cc index b9a11a45..6d27caed 100644 --- a/tools/generate_constants.cc +++ b/tools/generate_constants.cc @@ -43,13 +43,16 @@ std::vector GLOBAL_constants = // - https://www.c64-wiki.com/wiki/BASIC-ROM // Computes Mapping the Commodore 64, pages 103, 105, 113, 114, 116 + ConstEntry( "QUARTER", 0.25 ), ConstEntry( "HALF", 0.5 ), ConstEntry( "NEG_HALF", -0.5 ), ConstEntry( "ONE", 1.0 ), ConstEntry( "TEN", 10.0 ), ConstEntry( "NEG_32768", -32768.0 ), + ConstEntry( "HALF_PI", M_PI / 2.0 ), ConstEntry( "PI", M_PI ), + ConstEntry( "DOUBLE_PI", M_PI * 2.0 ), ConstEntry( "SQR_2", std::sqrt(2.0) ), ConstEntry( "INV_SQR_2", 1.0 / std::sqrt(2.0) ), ConstEntry( "LOG_2", std::log(2.0) ), From 6a1070c8ac34a0a59451bbf4073d5ee1e9865726 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 7 Feb 2020 17:57:46 +0100 Subject: [PATCH 40/66] added support for the Commander X16 memory layout --- Makefile | 341 +++++++++++------- c64/,,config_cx16.s | 136 +++++++ c64/aliases/,aliases_config.s | 3 + c64/aliases/,aliases_cpu.s | 4 +- c64/aliases/,aliases_rom_basic.s | 11 + c64/basic/,stubs/a408.reason.s | 1 + c64/basic/,stubs/a453.unknown.s | 1 + c64/basic/,stubs/a483.main.s | 9 +- c64/basic/,stubs/a57c.chrnch.s | 1 + c64/basic/,stubs/a644.new.s | 1 + c64/basic/,stubs/a659.setcharptr.s | 1 + c64/basic/,stubs/a71a.qplop.s | 1 + c64/basic/,stubs/a7e4.gone.s | 1 + c64/basic/,stubs/ad9e.frmevl.s | 1 + c64/basic/,stubs/ae86.eval.s | 1 + .../,stubs_math/a9c4.convert_FAC1_to_INT.s | 1 + c64/basic/,stubs_math/aabc.print_FAC1.s | 1 + c64/basic/,stubs_math/af7b.compute_TI.s | 1 + c64/basic/,stubs_math/af7e.math_stub.s | 1 + c64/basic/,stubs_math/af87.math_stub.s | 1 + c64/basic/,stubs_math/af9a.compute_ST.s | 1 + c64/basic/,stubs_math/b1aa.FACINX.s | 1 + c64/basic/,stubs_math/b391.GIVAYF.s | 1 + .../,stubs_math/b3a2.convert_Y_to_FAC1.s | 1 + .../,stubs_math/b794.convert_A_to_FAC1.s | 1 + c64/basic/,stubs_math/b7b5.STRVAL.s | 1 + .../,stubs_math/b7f7.convert_FAC1_to_ADDR.s | 1 + c64/basic/,stubs_math/b849.add_HALF_FAC1.s | 1 + c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s | 1 + .../,stubs_math/b947.inv_FAC1_mantissa.s | 1 + c64/basic/,stubs_math/b983.MULSHF.s | 1 + c64/basic/,stubs_math/b9ea.log_FAC1.s | 1 + c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s | 1 + c64/basic/,stubs_math/ba59.MLTPLY.s | 1 + c64/basic/,stubs_math/bae2.mul10_FAC1.s | 1 + c64/basic/,stubs_math/bafe.div10_FAC1_p.s | 1 + c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s | 1 + c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s | 1 + c64/basic/,stubs_math/bc39.sgn_FAC1.s | 1 + .../,stubs_math/bc3c.convert_A_to_FAC1.s | 1 + .../,stubs_math/bc44.convert_i16_to_FAC1.s | 1 + c64/basic/,stubs_math/bc58.abs_FAC1.s | 1 + c64/basic/,stubs_math/bc5b.FCOMP.s | 1 + c64/basic/,stubs_math/bc9b.QINT.s | 1 + c64/basic/,stubs_math/bccc.int_FAC1.s | 1 + c64/basic/,stubs_math/bcf3.FIN.s | 1 + c64/basic/,stubs_math/bd7e.FINLOG.s | 1 + c64/basic/,stubs_math/bddd.FOUT.s | 1 + c64/basic/,stubs_math/bf71.sqr_FAC1.s | 1 + c64/basic/,stubs_math/bf74.sqr_FAC2.s | 1 + c64/basic/,stubs_math/bf78.FPWR.s | 1 + c64/basic/,stubs_math/bf7b.FPWRT.s | 1 + c64/basic/,stubs_math/bfed.exp_FAC1.s | 1 + c64/basic/a533.linkprg.s | 1 + c64/basic/a68e.runc.s | 1 + c64/basic/a7ae.newstt.s | 1 + c64/basic/ab1e.strout.s | 1 + c64/basic/bdcd.linprt.s | 1 + .../dummy.s => board_m65/mega65_dummy.s} | 2 +- c64/basic/board_x16/cx16_dummy.s | 7 + c64/basic/c000.skip_gap.s | 1 + c64/basic/init/a000.cold_start_vector.s | 1 + c64/basic/init/a002.warm_start_vector.s | 1 + c64/basic/math/b850.sub_MEM_FAC1.s | 1 + c64/basic/math/b853.sub_FAC2_FAC1.s | 1 + c64/basic/math/b862.add_align_exponent.jmp.s | 1 + c64/basic/math/b867.add_MEM_FAC1.s | 1 + c64/basic/math/b8fe.normal_FAC1.jmp.s | 1 + c64/basic/math/ba28.mul_MEM_FAC1.s | 1 + c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s | 1 + c64/basic/math/bb0f.div_MEM_FAC1.s | 1 + c64/basic/math/bba2.mov_MEM_FAC1.jmp.s | 1 + c64/basic/math/bbc7.mov_r_FAC1_TMP2.s | 1 + c64/basic/math/bbca.mov_r_FAC1_TMP1.s | 1 + c64/basic/math/bbd0.mov_r_FAC1_VAR.s | 1 + c64/basic/math/bbd4.mov_r_FAC1_MEM.s | 1 + c64/basic/math/bbfc.mov_FAC2_FAC1.s | 1 + c64/basic/math/bc0c.mov_r_FAC1_FAC2.s | 1 + c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s | 1 + c64/basic/math/bc1b.round_FAC1.jmp.s | 1 + c64/basic/math/bfb4.toggle_sign_FAC1.s | 1 + c64/basic/math_consts/aea8.const_PI.s | 1 + c64/basic/math_consts/b1a5.const_NEG_32768.s | 1 + c64/basic/math_consts/b9bc.const_ONE.s | 1 + c64/basic/math_consts/b9d6.const_INV_SQR_2.s | 1 + c64/basic/math_consts/b9db.const_SQR_2.s | 1 + c64/basic/math_consts/b9e0.const_NEG_HALF.s | 1 + c64/basic/math_consts/b9e5.const_LOG_2.s | 1 + c64/basic/math_consts/baf9.const_TEN.s | 1 + c64/basic/math_consts/bf11.const_HALF.s | 1 + c64/basic/math_consts/bfbf.const_INV_LOG_2.s | 1 + c64/basic/math_consts/bfe8.const_ONE.s | 1 + c64/basic/rom_revision/a004.identifier.s | 1 + .../rom_revision/bf52.rom_revision_basic.s | 1 + .../{keyboard => assets}/programmable_keys.s | 0 .../{banking => board_m65}/4000.interop | 0 .../4000.mega65_vectable_kernal_1.s | 0 .../{banking => board_m65}/mega65_imports.s | 0 .../mega65_map_helpers.s | 0 .../{banking => board_m65}/mega65_proxies.s | 0 .../mega65_redirect_load_tape.s | 0 .../mega65_tape_normal_byte_store.s} | 0 c64/kernal/board_x16/cx16_dummy.s | 7 + c64/kernal/board_x16/cx16_stubs.s | 44 +++ c64/kernal/iec/iec_wait1ms.s | 1 + c64/kernal/init/e5a0.setup_vicii.s | 1 + c64/kernal/init/fce2.hw_entry_reset.s | 3 + c64/kernal/init/fd50.ramtas.s | 1 + c64/kernal/init/fda3.ioinit.s | 1 + c64/kernal/init/setup_pal_ntsc.s | 1 + .../interrupts/ea31.default_irq_handler.s | 8 + .../ea7e.ack_cia1_return_from_interrupt.s | 1 + .../interrupts/fe66.default_brk_handler.s | 4 + c64/kernal/{screen => iostack}/e50a.interop | 0 c64/kernal/{screen => iostack}/e50a.plot.s | 0 .../pop_keyboard_buffer.s | 0 c64/kernal/keyboard/chrin_keyboard.s | 1 + c64/kernal/keyboard/kb_matrix.s | 1 + c64/kernal/keyboard/kb_matrix_128.s | 1 + c64/kernal/keyboard/kb_matrix_65.s | 1 + c64/kernal/keyboard/kb_matrix_alwaysrepeat.s | 1 + c64/kernal/keyboard/kb_matrix_bucky.s | 1 + c64/kernal/keyboard/kb_matrix_bucky_filter.s | 1 + c64/kernal/keyboard/kb_matrix_joy.s | 1 + c64/kernal/keyboard/kb_matrix_lookup.s | 1 + c64/kernal/keyboard/kb_matrix_lookup_legacy.s | 1 + c64/kernal/keyboard/kb_matrix_row_keys.s | 1 + c64/kernal/keyboard/kb_matrix_row_offsets.s | 1 + c64/kernal/keyboard/keyboard_disconnect.s | 1 + c64/kernal/keyboard/scnkey.s | 1 + c64/kernal/keyboard/scnkey_128.s | 1 + c64/kernal/keyboard/scnkey_65.s | 1 + c64/kernal/keyboard/scnkey_legacy.s | 1 + c64/kernal/keyboard/scnkey_set_keytab.s | 1 + c64/kernal/keyboard/udtim_keyboard.s | 1 + c64/kernal/screen/chrout_screen.s | 1 + c64/kernal/screen/chrout_screen_clr.s | 1 + c64/kernal/screen/chrout_screen_control.s | 1 + c64/kernal/screen/chrout_screen_crsr.s | 1 + c64/kernal/screen/chrout_screen_del.s | 1 + c64/kernal/screen/chrout_screen_gfxtxt.s | 1 + c64/kernal/screen/chrout_screen_home.s | 1 + c64/kernal/screen/chrout_screen_ins.s | 1 + .../screen/chrout_screen_jumptable_codes.s | 1 + c64/kernal/screen/chrout_screen_quote.s | 1 + c64/kernal/screen/chrout_screen_return.s | 1 + c64/kernal/screen/chrout_screen_rvs.s | 1 + c64/kernal/screen/chrout_screen_shift_onoff.s | 1 + c64/kernal/screen/chrout_screen_stop.s | 1 + c64/kernal/screen/chrout_screen_tab.s | 1 + c64/kernal/screen/cursor.s | 1 + c64/kernal/screen/cursor_enable.s | 1 + c64/kernal/screen/cursor_show.s | 1 + c64/kernal/screen/e544.clear_screen.s | 1 + c64/kernal/screen/e566.cursor_home.s | 1 + .../screen/e56c.screen_calculate_pointers.s | 1 + c64/kernal/screen/e8ea.screen_scroll_up.s | 1 + c64/kernal/screen/e9ff.screen_clear_line.s | 1 + c64/kernal/screen/screen.s | 1 + .../screen/screen_advance_to_next_line.s | 1 + c64/kernal/screen/screen_calculate_pnt_user.s | 1 + .../screen/screen_calculate_pntr_lnmx.s | 1 + .../screen/screen_check_space_ends_line.s | 1 + c64/kernal/screen/screen_code_to_petscii.s | 1 + c64/kernal/screen/screen_get_cliped_pntr.s | 1 + .../screen/screen_get_logical_line_end_ptr.s | 1 + c64/kernal/screen/screen_grow_logical_line.s | 1 + c64/kernal/screen/screen_off.s | 1 + c64/kernal/screen/screen_on.s | 1 + c64/kernal/screen/screen_preserve_sal_eal.s | 1 + c64/kernal/screen/screen_restore_sal_eal.s | 1 + doc/Development.md | 16 +- tools/build_segment.cc | 18 +- 173 files changed, 605 insertions(+), 155 deletions(-) create mode 100644 c64/,,config_cx16.s rename c64/basic/{banking/dummy.s => board_m65/mega65_dummy.s} (60%) create mode 100644 c64/basic/board_x16/cx16_dummy.s rename c64/kernal/{keyboard => assets}/programmable_keys.s (100%) rename c64/kernal/{banking => board_m65}/4000.interop (100%) rename c64/kernal/{banking => board_m65}/4000.mega65_vectable_kernal_1.s (100%) rename c64/kernal/{banking => board_m65}/mega65_imports.s (100%) rename c64/kernal/{banking => board_m65}/mega65_map_helpers.s (100%) rename c64/kernal/{banking => board_m65}/mega65_proxies.s (100%) rename c64/kernal/{banking => board_m65}/mega65_redirect_load_tape.s (100%) rename c64/kernal/{tape/tape_normal_byte_store_mega65.s => board_m65/mega65_tape_normal_byte_store.s} (100%) create mode 100644 c64/kernal/board_x16/cx16_dummy.s create mode 100644 c64/kernal/board_x16/cx16_stubs.s rename c64/kernal/{screen => iostack}/e50a.interop (100%) rename c64/kernal/{screen => iostack}/e50a.plot.s (100%) rename c64/kernal/{keyboard => iostack}/pop_keyboard_buffer.s (100%) diff --git a/Makefile b/Makefile index b80ef23f..49f6bd6e 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,8 @@ SRCDIR_BASIC = $(SRCDIR_COMMON) \ c64/basic \ c64/basic/,stubs \ c64/basic/,stubs_math \ - c64/basic/banking \ + c64/basic/board_m65 \ + c64/basic/board_x16 \ c64/basic/commands \ c64/basic/init \ c64/basic/math \ @@ -23,7 +24,8 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \ c64/kernal \ c64/kernal/,stubs \ c64/kernal/assets \ - c64/kernal/banking \ + c64/kernal/board_m65 \ + c64/kernal/board_x16 \ c64/kernal/iec \ c64/kernal/iec_fast \ c64/kernal/init \ @@ -50,19 +52,21 @@ GEN_KERNAL = # List of build directories -DIR_CUSTOM = build/target_custom -DIR_GENERIC = build/target_generic -DIR_TESTING = build/target_testing -DIR_MEGA65 = build/target_mega65 -DIR_ULTIMATE64 = build/target_ultimate64 +DIR_CUS = build/target_custom +DIR_GEN = build/target_generic +DIR_TST = build/target_testing +DIR_M65 = build/target_mega65 +DIR_U64 = build/target_ultimate64 +DIR_X16 = build/target_cx16 # List of config files -CFG_CUSTOM = c64/,,config_custom.s -CFG_GENERIC = c64/,,config_generic.s -CFG_TESTING = c64/,,config_testing.s -CFG_MEGA65 = c64/,,config_mega65.s -CFG_ULTIMATE64 = c64/,,config_ultimate64.s +CFG_CUSTOM = c64/,,config_custom.s +CFG_GEN = c64/,,config_generic.s +CFG_TESTING = c64/,,config_testing.s +CFG_M65 = c64/,,config_mega65.s +CFG_U64 = c64/,,config_ultimate64.s +CFG_X16 = c64/,,config_cx16.s # Dependencies - helper variables @@ -84,27 +88,43 @@ TOOLS_LIST = $(pathsubst tools/%,build/tools/%,$(basename $(SRC_TOOLS))) # List of targets -STD_TARGET_LIST_CUSTOM = build/kernal_custom.rom build/basic_custom.rom -STD_TARGET_LIST_GENERIC = build/kernal_generic.rom build/basic_generic.rom -STD_TARGET_LIST_TESTING = build/kernal_testing.rom build/basic_testing.rom -STD_TARGET_LIST_ULTIMATE64 = build/kernal_ultimate64.rom build/basic_ultimate64.rom -STD_TARGET_LIST_MEGA65 = build/mega65.rom +TARGET_CUS_B = build/kernal_custom.rom +TARGET_GEN_B = build/kernal_generic.rom +TARGET_TST_B = build/kernal_testing.rom +TARGET_U64_B = build/kernal_ultimate64.rom -STD_TARGET_LIST = build/chargen.rom \ - $(STD_TARGET_LIST_CUSTOM) \ - $(STD_TARGET_LIST_GENERIC) \ - $(STD_TARGET_LIST_TESTING) \ - $(STD_TARGET_LIST_MEGA65) \ - $(STD_TARGET_LIST_ULTIMATE64) +TARGET_CUS_K = build/kernal_custom.rom +TARGET_GEN_K = build/kernal_generic.rom +TARGET_TST_K = build/kernal_testing.rom +TARGET_U64_K = build/kernal_ultimate64.rom -EXT_TARGET_LIST = build/mega65.rom +TARGET_M65_x = build/mega65.rom +TARGET_X16_x = build/cx16-dummy.rom -SEG_LIST_MEGA65 = $(DIR_MEGA65)/basic.seg_0 \ - $(DIR_MEGA65)/basic.seg_1 \ - $(DIR_MEGA65)/kernal.seg_0 \ - $(DIR_MEGA65)/kernal.seg_1 +TARGET_LIST_CUS = $(TARGET_CUS_B) $(TARGET_CUS_K) +TARGET_LIST_GEN = $(TARGET_GEN_B) $(TARGET_GEN_K) +TARGET_LIST_TST = $(TARGET_TST_B) $(TARGET_TST_K) +TARGET_LIST_U64 = $(TARGET_U64_B) $(TARGET_U64_K) -REL_TARGET_LIST = $(pathsubst build/%,bin/%, $(STD_TARGET_LIST)) +TARGET_LIST = build/chargen.rom \ + $(TARGET_LIST_CUS) \ + $(TARGET_LIST_GEN) \ + $(TARGET_LIST_TST) \ + $(TARGET_M65_x) \ + $(TARGET_LIST_U64) \ + $(TARGET_X16_x) + +SEG_LIST_M65 = $(DIR_M65)/basic.seg_0 \ + $(DIR_M65)/basic.seg_1 \ + $(DIR_M65)/kernal.seg_0 \ + $(DIR_M65)/kernal.seg_1 + +SEG_LIST_X16 = $(DIR_X16)/basic.seg_0 \ + $(DIR_X16)/basic.seg_1 \ + $(DIR_X16)/kernal.seg_0 \ + $(DIR_X16)/kernal.seg_1 + +REL_TARGET_LIST = $(TARGET_LIST_CUS) $(TARGET_LIST_GEN) $(TARGET_LIST_TST) $(TARGET_M65_x) $(TARGET_LIST_U64) # Misc strings @@ -119,14 +139,14 @@ GIT_COMMIT:= $(shell git log -1 --pretty='%h' | tr '[:lower:]' '[:upper:]') .PHONY: all clean updatebin all: - $(MAKE) -j64 --output-sync=target $(STD_TARGET_LIST) $(EXT_TARGET_LIST) + $(MAKE) -j64 --output-sync=target $(TARGET_LIST) $(EXT_TARGET_LIST) clean: @rm -rf build c64/basic/combined.s c64/kernal/combined.s updatebin: - $(MAKE) -j64 --output-sync=target $(STD_TARGET_LIST) $(EXT_TARGET_LIST) $(TOOL_RELEASE) - $(TOOL_RELEASE) -i ./build -o ./bin basic_generic.rom kernal_generic.rom basic_testing.rom kernal_testing.rom basic_ultimate64.rom kernal_ultimate64.rom mega65.rom + $(MAKE) -j64 --output-sync=target $(TARGET_LIST) $(TOOL_RELEASE) + $(TOOL_RELEASE) -i ./build -o ./bin $(pathsubst build/%,./%, $(REL_TARGET_LIST)) cp build/chargen.rom bin/chargen.rom # Rules - tools @@ -154,61 +174,67 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies - BASIC and KERNAL -$(DIR_CUSTOM)/OUTB_X.BIN $(DIR_CUSTOM)/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_CUSTOM) $(DIR_CUSTOM)/KERNAL_combined.sym -$(DIR_GENERIC)/OUTB_X.BIN $(DIR_GENERIC)/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_GENERIC) $(DIR_GENERIC)/KERNAL_combined.sym -$(DIR_TESTING)/OUTB_X.BIN $(DIR_TESTING)/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_TESTING) $(DIR_TESTING)/KERNAL_combined.sym -$(DIR_ULTIMATE64)/OUTB_X.BIN $(DIR_ULTIMATE64)/BASIC_combined.vs: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_ULTIMATE64) $(DIR_ULTIMATE64)/KERNAL_combined.sym +$(DIR_CUS)/OUTB_x.BIN $(DIR_CUS)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_CUS) $(DIR_CUS)/KERNAL_combined.sym +$(DIR_GEN)/OUTB_x.BIN $(DIR_GEN)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_GEN) $(DIR_GEN)/KERNAL_combined.sym +$(DIR_TST)/OUTB_x.BIN $(DIR_TST)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_TST) $(DIR_TST)/KERNAL_combined.sym +$(DIR_U64)/OUTB_x.BIN $(DIR_U64)/BASIC_combined.vs: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_U64) $(DIR_U64)/KERNAL_combined.sym -$(DIR_CUSTOM)/OUTK_X.BIN $(DIR_CUSTOM)/KERNAL_combined.vs $(DIR_CUSTOM)/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_CUSTOM) -$(DIR_GENERIC)/OUTK_X.BIN $(DIR_GENERIC)/KERNAL_combined.vs $(DIR_GENERIC)/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_GENERIC) -$(DIR_TESTING)/OUTK_X.BIN $(DIR_TESTING)KERNAL_combined.vs $(DIR_TESTING)/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_TESTING) -$(DIR_ULTIMATE64)/OUTK_X.BIN $(DIR_ULTIMATE64)/KERNAL_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_ULTIMATE64) +$(DIR_CUS)/OUTK_x.BIN $(DIR_CUS)/KERNAL_combined.vs $(DIR_CUS)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_CUS) +$(DIR_GEN)/OUTK_x.BIN $(DIR_GEN)/KERNAL_combined.vs $(DIR_GEN)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_GEN) +$(DIR_TST)/OUTK_x.BIN $(DIR_TST)/KERNAL_combined.vs $(DIR_TST)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_TST) +$(DIR_U64)/OUTK_x.BIN $(DIR_U64)/KERNAL_combined.vs $(DIR_U64)/KERNAL_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_U64) +$(DIR_M65)/OUTB_0.BIN $(DIR_M65)/BASIC_0_combined.vs $(DIR_M65)/BASIC_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_M65) $(DIR_M65)/KERNAL_0_combined.sym +$(DIR_M65)/OUTK_0.BIN $(DIR_M65)/KERNAL_0_combined.vs $(DIR_M65)/KERNAL_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_M65) -$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/BASIC_0_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym -$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) +$(DIR_X16)/OUTB_0.BIN $(DIR_X16)/BASIC_0_combined.vs $(DIR_X16)/BASIC_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_X16) $(DIR_X16)/KERNAL_0_combined.sym +$(DIR_X16)/OUTK_0.BIN $(DIR_X16)/KERNAL_0_combined.vs $(DIR_X16)/KERNAL_0_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_X16) -$(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1_combined.vs $(DIR_MEGA65)/BASIC_1_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym $(DIR_MEGA65)/BASIC_0_combined.sym -$(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: \ - $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_MEGA65) $(DIR_MEGA65)/KERNAL_0_combined.sym +$(DIR_M65)/basic.seg_1 $(DIR_M65)/BASIC_1_combined.vs $(DIR_M65)/BASIC_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_M65) $(DIR_M65)/KERNAL_0_combined.sym $(DIR_M65)/BASIC_0_combined.sym +$(DIR_M65)/kernal.seg_1 $(DIR_M65)/KERNAL_1_combined.vs $(DIR_M65)/KERNAL_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_M65) $(DIR_M65)/KERNAL_0_combined.sym -$(DIR_CUSTOM)/OUTX_X.BIN: $(DIR_CUSTOM)/OUTB_X.BIN $(DIR_CUSTOM)/OUTK_X.BIN -$(DIR_GENERIC)/OUTX_X.BIN: $(DIR_GENERIC)/OUTB_X.BIN $(DIR_GENERIC)/OUTK_X.BIN -$(DIR_TESTING)/OUTX_X.BIN: $(DIR_TESTING)/OUTB_X.BIN $(DIR_TESTING)/OUTK_X.BIN -$(DIR_MEGA65)/OUTX_0.BIN: $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN -$(DIR_ULTIMATE64)/OUTX_X.BIN: $(DIR_ULTIMATE64)/OUTB_X.BIN $(DIR_ULTIMATE64)/OUTK_X.BIN +$(DIR_X16)/basic.seg_1 $(DIR_X16)/BASIC_1_combined.vs $(DIR_X16)/BASIC_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_BASIC) $(CFG_X16) $(DIR_M65)/KERNAL_0_combined.sym $(DIR_X16)/BASIC_0_combined.sym +$(DIR_X16)/kernal.seg_1 $(DIR_X16)/KERNAL_1_combined.vs $(DIR_X16)/KERNAL_1_combined.sym: \ + $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(DEP_KERNAL) $(CFG_X16) $(DIR_X16)/KERNAL_0_combined.sym -build/kernal_custom.rom: $(DIR_CUSTOM)/OUTX_X.BIN -build/kernal_generic.rom: $(DIR_GENERIC)/OUTX_X.BIN -build/kernal_testing.rom: $(DIR_TESTING)/OUTX_X.BIN -build/kernal_ultimate64.rom: $(DIR_ULTIMATE64)/OUTX_X.BIN +$(DIR_CUS)/OUTx_x.BIN: $(DIR_CUS)/OUTB_x.BIN $(DIR_CUS)/OUTK_x.BIN +$(DIR_GEN)/OUTx_x.BIN: $(DIR_GEN)/OUTB_x.BIN $(DIR_GEN)/OUTK_x.BIN +$(DIR_TST)/OUTx_x.BIN: $(DIR_TST)/OUTB_x.BIN $(DIR_TST)/OUTK_x.BIN +$(DIR_M65)/OUTx_0.BIN: $(DIR_M65)/OUTB_0.BIN $(DIR_M65)/OUTK_0.BIN +$(DIR_U64)/OUTx_x.BIN: $(DIR_U64)/OUTB_x.BIN $(DIR_U64)/OUTK_x.BIN +$(DIR_X16)/OUTx_0.BIN: $(DIR_X16)/OUTB_0.BIN $(DIR_X16)/OUTK_0.BIN -build/basic_custom.rom: $(DIR_CUSTOM)/OUTX_X.BIN -build/basic_generic.rom: $(DIR_GENERIC)/OUTX_X.BIN -build/basic_testing.rom: $(DIR_TESTING)/OUTX_X.BIN -build/basic_ultimate64.rom: $(DIR_ULTIMATE64)/OUTX_X.BIN +$(TARGET_CUS_B): $(DIR_CUS)/OUTx_x.BIN +$(TARGET_GEN_B): $(DIR_GEN)/OUTx_x.BIN +$(TARGET_TST_B): $(DIR_TST)/OUTx_x.BIN +$(TARGET_U64_B): $(DIR_U64)/OUTx_x.BIN -$(DIR_MEGA65)/kernal.seg_0: $(DIR_MEGA65)/OUTX_0.BIN -$(DIR_MEGA65)/basic.seg_0: $(DIR_MEGA65)/OUTX_0.BIN +$(TARGET_CUS_K): $(DIR_CUS)/OUTx_x.BIN +$(TARGET_GEN_K): $(DIR_GEN)/OUTx_x.BIN +$(TARGET_TST_K): $(DIR_TST)/OUTx_x.BIN +$(TARGET_U64_K): $(DIR_U64)/OUTx_x.BIN -build/symbols_custom.vs: $(DIR_CUSTOM)/BASIC_combined.vs $(DIR_CUSTOM)/KERNAL_combined.vs -build/symbols_generic.vs: $(DIR_GENERIC)/BASIC_combined.vs $(DIR_GENERIC)/KERNAL_combined.vs -build/symbols_testing.vs: $(DIR_TESTING)/BASIC_combined.vs $(DIR_TESTING)/KERNAL_combined.vs -build/symbols_mega65_0.vs: $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.vs -build/symbols_ultimate64.vs: $(DIR_ULTIMATE64)/BASIC_combined.vs $(DIR_ULTIMATE64)/KERNAL_combined.vs +build/symbols_custom.vs: $(DIR_CUS)/BASIC_combined.vs $(DIR_CUS)/KERNAL_combined.vs +build/symbols_generic.vs: $(DIR_GEN)/BASIC_combined.vs $(DIR_GEN)/KERNAL_combined.vs +build/symbols_testing.vs: $(DIR_TST)/BASIC_combined.vs $(DIR_TST)/KERNAL_combined.vs +build/symbols_ultimate64.vs: $(DIR_U64)/BASIC_combined.vs $(DIR_U64)/KERNAL_combined.vs -# Rules - BASIC and KERNAL +# Rules - BASIC and KERNAL intermediate files build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT) @mkdir -p build/,generated @@ -218,91 +244,138 @@ build/,generated/float_constants.s: $(TOOL_GENERATE_CONSTANTS) @mkdir -p build/,generated $(TOOL_GENERATE_CONSTANTS) -o build/,generated/float_constants.s -.PRECIOUS: build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs -build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs: +.PRECIOUS: build/target_%/OUTB_x.BIN build/target_%/BASIC_combined.vs +build/target_%/OUTB_x.BIN build/target_%/BASIC_combined.vs: @mkdir -p build/target_$* @rm -f $@* build/target_$*/BASIC* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s BASIC -i BASIC-$* -o OUTB_X.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC) $(GEN_BASIC) + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s BASIC -i BASIC-$* -o OUTB_x.BIN -d build/target_$* -l a000 -h e4d2 c64/,,config_$*.s $(SRCDIR_BASIC) $(GEN_BASIC) -.PRECIOUS: build/target_%/OUTK_X.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym -build/target_%/OUTK_X.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym: +.PRECIOUS: build/target_%/OUTK_x.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym +build/target_%/OUTK_x.BIN build/target_%/KERNAL_combined.vs build/target_%/KERNAL_combined.sym: @mkdir -p build/target_$* @rm -f $@* build/target_$*/KERNAL* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s KERNAL -i KERNAL-$* -o OUTK_X.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL) + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r STD -s KERNAL -i KERNAL-$* -o OUTK_x.BIN -d build/target_$* -l e4d3 -h ffff c64/,,config_$*.s $(SRCDIR_KERNAL) $(GEN_KERNAL) -$(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/BASIC_0_combined.vs $(DIR_MEGA65)/BASIC_0_combined.sym: - @mkdir -p $(DIR_MEGA65) - @rm -f $@* $(DIR_MEGA65)/BASIC_0* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d $(DIR_MEGA65) -l a000 -h e4d2 $(CFG_MEGA65) $(SRCDIR_BASIC) $(GEN_BASIC) +# Rules - BASIC and KERNAL intermediate files, for Mega65 -$(DIR_MEGA65)/OUTK_0.BIN $(DIR_MEGA65)/KERNAL_0_combined.vs $(DIR_MEGA65)/KERNAL_0_combined.sym: - @mkdir -p $(DIR_MEGA65) - @rm -f $@* $(DIR_MEGA65)/KERNAL_0* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d $(DIR_MEGA65) -l e4d3 -h ffff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) +$(DIR_M65)/OUTB_0.BIN $(DIR_M65)/BASIC_0_combined.vs $(DIR_M65)/BASIC_0_combined.sym: + @mkdir -p $(DIR_M65) + @rm -f $@* $(DIR_M65)/BASIC_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d $(DIR_M65) -l a000 -h e4d2 $(CFG_M65) $(SRCDIR_BASIC) $(GEN_BASIC) -$(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1_combined.vs $(DIR_MEGA65)/BASIC_1_combined.sym: - @mkdir -p $(DIR_MEGA65) - @rm -f $@* $(DIR_MEGA65)/basic.seg_1 $(DIR_MEGA65)/BASIC_1* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_MEGA65) -l 4000 -h 5fff $(CFG_MEGA65) $(SRCDIR_BASIC) $(GEN_BASIC) +$(DIR_M65)/OUTK_0.BIN $(DIR_M65)/KERNAL_0_combined.vs $(DIR_M65)/KERNAL_0_combined.sym: + @mkdir -p $(DIR_M65) + @rm -f $@* $(DIR_M65)/KERNAL_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d $(DIR_M65) -l e4d3 -h ffff $(CFG_M65) $(SRCDIR_KERNAL) $(GEN_KERNAL) -$(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1_combined.vs $(DIR_MEGA65)/KERNAL_1_combined.sym: - @mkdir -p $(DIR_MEGA65) - @rm -f $@* $(DIR_MEGA65)/kernal.seg_1 $(DIR_MEGA65)/KERNAL_1* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d $(DIR_MEGA65) -l 4000 -h 5fff $(CFG_MEGA65) $(SRCDIR_KERNAL) $(GEN_KERNAL) +$(DIR_M65)/basic.seg_1 $(DIR_M65)/BASIC_1_combined.vs $(DIR_M65)/BASIC_1_combined.sym: + @mkdir -p $(DIR_M65) + @rm -f $@* $(DIR_M65)/basic.seg_1 $(DIR_M65)/BASIC_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_M65) -l 4000 -h 5fff $(CFG_M65) $(SRCDIR_BASIC) $(GEN_BASIC) -.PRECIOUS: build/target_%/OUTX_X.BIN -build/target_%/OUTX_X.BIN: - cat build/target_$*/OUTB_X.BIN build/target_$*/OUTK_X.BIN > $@ +$(DIR_M65)/kernal.seg_1 $(DIR_M65)/KERNAL_1_combined.vs $(DIR_M65)/KERNAL_1_combined.sym: + @mkdir -p $(DIR_M65) + @rm -f $@* $(DIR_M65)/kernal.seg_1 $(DIR_M65)/KERNAL_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d $(DIR_M65) -l 4000 -h 5fff $(CFG_M65) $(SRCDIR_KERNAL) $(GEN_KERNAL) + +# Rules - BASIC and KERNAL intermediate files, for Commander X16 + +$(DIR_X16)/OUTB_0.BIN $(DIR_X16)/BASIC_0_combined.vs $(DIR_X16)/BASIC_0_combined.sym: + @mkdir -p $(DIR_X16) + @rm -f $@* $(DIR_X16)/BASIC_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r X16 -s BASIC_0 -i BASIC_0-mega65 -o OUTB_0.BIN -d $(DIR_X16) -l c000 -h e4d2 $(CFG_X16) $(SRCDIR_BASIC) $(GEN_BASIC) + +$(DIR_X16)/OUTK_0.BIN $(DIR_X16)/KERNAL_0_combined.vs $(DIR_X16)/KERNAL_0_combined.sym: + @mkdir -p $(DIR_X16) + @rm -f $@* $(DIR_X16)/KERNAL_0* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r X16 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d $(DIR_X16) -l e4d3 -h ffff $(CFG_X16) $(SRCDIR_KERNAL) $(GEN_KERNAL) + +$(DIR_X16)/basic.seg_1 $(DIR_X16)/BASIC_1_combined.vs $(DIR_X16)/BASIC_1_combined.sym: + @mkdir -p $(DIR_X16) + @rm -f $@* $(DIR_X16)/basic.seg_1 $(DIR_X16)/BASIC_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r X16 -s BASIC_1 -i BASIC_1-mega65 -o basic.seg_1 -d $(DIR_X16) -l a000 -h bfff $(CFG_X16) $(SRCDIR_BASIC) $(GEN_BASIC) + +$(DIR_X16)/kernal.seg_1 $(DIR_X16)/KERNAL_1_combined.vs $(DIR_X16)/KERNAL_1_combined.sym: + @mkdir -p $(DIR_X16) + @rm -f $@* $(DIR_X16)/kernal.seg_1 $(DIR_X16)/KERNAL_1* + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r X16 -s KERNAL_1 -i KERNAL_1-mega65 -o kernal.seg_1 -d $(DIR_X16) -l a000 -h bfff $(CFG_X16) $(SRCDIR_KERNAL) $(GEN_KERNAL) + +# Rules - BASIC and KERNAL + +.PRECIOUS: build/target_%/OUTx_x.BIN +build/target_%/OUTx_x.BIN: + cat build/target_$*/OUTB_x.BIN build/target_$*/OUTK_x.BIN > $@ .PRECIOUS: build/kernal_%.rom build/kernal_%.rom: - dd if=build/target_$*/OUTX_X.BIN bs=8192 count=1 skip=2 of=$@ + dd if=build/target_$*/OUTx_x.BIN bs=8192 count=1 skip=2 of=$@ .PRECIOUS: build/basic_%.rom build/basic_%.rom: - dd if=build/target_$*/OUTX_X.BIN bs=8192 count=1 skip=0 of=$@ + dd if=build/target_$*/OUTx_x.BIN bs=8192 count=1 skip=0 of=$@ .PRECIOUS: build/symbols_%.vs build/symbols_%.vs: sort build/target_$*/BASIC_combined.vs build/target_$*/KERNAL_combined.vs | uniq | grep -v "__" > $@ -$(DIR_MEGA65)/OUTX_0.BIN: - cat $(DIR_MEGA65)/OUTB_0.BIN $(DIR_MEGA65)/OUTK_0.BIN > $@ +$(DIR_M65)/OUTx_0.BIN: + cat $(DIR_M65)/OUTB_0.BIN $(DIR_M65)/OUTK_0.BIN > $@ -$(DIR_MEGA65)/kernal.seg_0: - dd if=$(DIR_MEGA65)/OUTX_0.BIN bs=8192 count=1 skip=2 of=$@ +$(DIR_M65)/kernal.seg_0: $(DIR_M65)/OUTx_0.BIN + dd if=$(DIR_M65)/OUTx_0.BIN bs=8192 count=1 skip=2 of=$@ -$(DIR_MEGA65)/basic.seg_0: - dd if=$(DIR_MEGA65)/OUTX_0.BIN bs=8192 count=1 skip=0 of=$@ +$(DIR_M65)/basic.seg_0: $(DIR_M65)/OUTx_0.BIN + dd if=$(DIR_M65)/OUTx_0.BIN bs=8192 count=1 skip=0 of=$@ -build/kernal_hybrid.rom: kernal $(DIR_GENERIC)/OUTK_X.BIN +$(DIR_X16)/OUTx_0.BIN: + cat $(DIR_X16)/OUTB_0.BIN $(DIR_X16)/OUTK_0.BIN > $@ + +$(DIR_X16)/kernal.seg_0: $(DIR_X16)/OUTx_0.BIN + dd if=$(DIR_X16)/OUTx_0.BIN bs=8192 count=1 skip=1 of=$@ + +$(DIR_X16)/basic.seg_0: $(DIR_X16)/OUTx_0.BIN + dd if=$(DIR_X16)/OUTx_0.BIN bs=8192 count=1 skip=0 of=$@ + +build/kernal_hybrid.rom: kernal $(DIR_GEN)/OUTK_x.BIN @echo @echo $(HYBRID_WARNING) @echo (dd if=kernal bs=1140 count=1 skip=0 ; \ echo " > HYBRID ROM, DON'T DISTRIBUTE <" ; \ dd if=kernal bs=1 count=58 skip=1176 ; \ - cat $(DIR_GENERIC)/OUTK_X.BIN) > $@ + cat $(DIR_GEN)/OUTK_x.BIN) > $@ -build/symbols_hybrid.vs: $(DIR_GENERIC)/KERNAL_combined.vs - sort $(DIR_GENERIC)/KERNAL_combined.vs | uniq | grep -v "__" > $@ +build/symbols_hybrid.vs: $(DIR_GEN)/KERNAL_combined.vs + sort $(DIR_GEN)/KERNAL_combined.vs | uniq | grep -v "__" > $@ -# Rules - platform 'Mega 65' specific +# Rules - platform 'Mega65' specific -build/mega65.rom: $(SEG_LIST_MEGA65) build/chargen.rom - dd if=/dev/zero bs=8192 count=1 of=build/padding___08_KB - dd if=/dev/zero bs=8192 count=8 of=build/padding___64_KB - cat build/padding___08_KB > build/mega65.rom - cat build/padding___08_KB >> build/mega65.rom - cat $(DIR_MEGA65)/kernal.seg_1 >> build/mega65.rom - cat $(DIR_MEGA65)/basic.seg_1 >> build/mega65.rom - cat build/padding___08_KB >> build/mega65.rom - cat $(DIR_MEGA65)/basic.seg_0 >> build/mega65.rom - cat build/chargen.rom >> build/mega65.rom - cat build/chargen.rom >> build/mega65.rom - cat $(DIR_MEGA65)/kernal.seg_0 >> build/mega65.rom - cat build/padding___64_KB >> build/mega65.rom - rm -f build/padding___* +$(TARGET_M65_x): $(SEG_LIST_M65) build/chargen.rom + dd if=/dev/zero bs=8192 count=1 of=build/m65_padding_08_KB + dd if=/dev/zero bs=8192 count=8 of=build/m65_padding_64_KB + cat build/m65_padding_08_KB > $(TARGET_M65_x) + cat build/m65_padding_08_KB >> $(TARGET_M65_x) + cat $(DIR_M65)/kernal.seg_1 >> $(TARGET_M65_x) + cat $(DIR_M65)/basic.seg_1 >> $(TARGET_M65_x) + cat build/m65_padding_08_KB >> $(TARGET_M65_x) + cat $(DIR_M65)/basic.seg_0 >> $(TARGET_M65_x) + cat build/chargen.rom >> $(TARGET_M65_x) + cat build/chargen.rom >> $(TARGET_M65_x) + cat $(DIR_M65)/kernal.seg_0 >> $(TARGET_M65_x) + cat build/m65_padding_64_KB >> $(TARGET_M65_x) + rm -f build/m65_padding_* + +# Rules - platform 'Commander X16' specific + +$(TARGET_X16_x): $(SEG_LIST_X16) build/chargen.rom + dd if=/dev/zero bs=8192 count=1 of=build/x16_padding_08_KB + dd if=/dev/zero bs=8192 count=8 of=build/x16_padding_64_KB + cat $(DIR_X16)/basic.seg_0 > $(TARGET_X16_x) + cat $(DIR_X16)/kernal.seg_0 >> $(TARGET_X16_x) + cat build/chargen.rom >> $(TARGET_X16_x) + cat $(DIR_X16)/basic.seg_1 >> $(TARGET_X16_x) + cat $(DIR_X16)/kernal.seg_1 >> $(TARGET_X16_x) + rm -f build/x16_padding_* # Rules - tests @@ -325,8 +398,8 @@ test_generic_x128: build/kernal_generic.rom build/basic_generic.rom build/symbol test_testing: build/kernal_testing.rom build/basic_testing.rom build/symbols_testing.vs x64 -kernal build/kernal_testing.rom -basic build/basic_testing.rom -moncommands build/symbols_testing.vs -1 $(TESTTAPE) -8 $(TESTDISK) -test_mega65: build/mega65.rom - ../xemu/build/bin/xmega65.native -dmarev 2 -forcerom -loadrom build/mega65.rom +test_mega65: $(TARGET_M65_x) + ../xemu/build/bin/xmega65.native -dmarev 2 -forcerom -loadrom $(TARGET_M65_x) test_ultimate64: build/kernal_ultimate64.rom build/basic_ultimate64.rom build/symbols_ultimate64.vs x64 -kernal build/kernal_ultimate64.rom -basic build/basic_ultimate64.rom -moncommands build/symbols_ultimate64.vs -1 $(TESTTAPE) -8 $(TESTDISK) @@ -346,6 +419,6 @@ test_m65: build/mega65.rom testremote: build/kernal_custom.rom build/basic_custom.rom build/symbols_custom.vs x64 -kernal build/kernal_custom.rom -basic build/basic_custom.rom -moncommands build/symbols_custom.vs -remotemonitor -testsimilarity: $(TOOL_SIMILARITY) $(DIR_GENERIC)/OUTX_X.BIN kernal basic - $(TOOL_SIMILARITY) kernal $(DIR_GENERIC)/OUTX_X.BIN - $(TOOL_SIMILARITY) basic $(DIR_GENERIC)/OUTX_X.BIN +testsimilarity: $(TOOL_SIMILARITY) $(DIR_GEN)/OUTx_x.BIN kernal basic + $(TOOL_SIMILARITY) kernal $(DIR_GEN)/OUTx_x.BIN + $(TOOL_SIMILARITY) basic $(DIR_GEN)/OUTx_x.BIN diff --git a/c64/,,config_cx16.s b/c64/,,config_cx16.s new file mode 100644 index 00000000..9b94dcd9 --- /dev/null +++ b/c64/,,config_cx16.s @@ -0,0 +1,136 @@ + +.const CONFIG_ID = $04 // should be 1 byte, different for each config file! +.encoding "petscii_upper" + +// +// Please read CONFIG.md before modifying this file! +// + +// Idea: +// - settings file for the Commander X16 machine + + + +// Hardware platform and brand + +#define CONFIG_PLATFORM_COMMANDER_X16 + +// #define CONFIG_MB_MEGA_65 +// #define CONFIG_MB_ULTIMATE_64 + +#define CONFIG_BRAND_CUSTOM_BUILD +// #define CONFIG_BRAND_GENERIC +// #define CONFIG_BRAND_TESTING +// #define CONFIG_BRAND_MEGA_65 +// #define CONFIG_BRAND_ULTIMATE_64 + +.const CONFIG_CUSTOM_BRAND = @"COMMANDER X16" + + +// Processor instruction set + +// #define CONFIG_CPU_MOS_6502 +#define CONFIG_CPU_WDC_65C02 +// #define CONFIG_CPU_CSG_65CE02 +// #define CONFIG_CPU_M65_45GS02 +// #define CONFIG_CPU_WDC_65816 + + +// Memory model + +#define CONFIG_MEMORY_MODEL_38K +// #define CONFIG_MEMORY_MODEL_60K + + +// I/O devices + +// #define CONFIG_IEC +// #define CONFIG_IEC_DOLPHINDOS +// #define CONFIG_IEC_DOLPHINDOS_FAST +// #define CONFIG_IEC_JIFFYDOS +// #define CONFIG_IEC_JIFFYDOS_BLANK + +// #define CONFIG_TAPE_NORMAL +// #define CONFIG_TAPE_TURBO +// #define CONFIG_TAPE_AUTODETECT +// #define CONFIG_TAPE_NO_KEY_SENSE +// #define CONFIG_TAPE_NO_MOTOR_CONTROL +// #define CONFIG_TAPE_NO_ERROR_CORRECTION + + +// Multiple SID support + +// #define CONFIG_SID_2ND +.const CONFIG_SID_2ND_ADDRESS = $D440 + +// #define CONFIG_SID_3RD +.const CONFIG_SID_3RD_ADDRESS = $D480 + +// #define CONFIG_SID_D4XX +// #define CONFIG_SID_D5XX + + +// Keyboard settings + +// #define CONFIG_LEGACY_SCNKEY +// #define CONFIG_KEYBOARD_C128 +// #define CONFIG_KEYBOARD_C128_CAPS_LOCK +// #define CONFIG_KEYBOARD_C65 // untested +// #define CONFIG_KEYBOARD_C65_CAPS_LOCK // untested +// #define CONFIG_KEY_REPEAT_DEFAULT +// #define CONFIG_KEY_REPEAT_ALWAYS +// #define CONFIG_KEY_FAST_SCAN +// #define CONFIG_JOY1_CURSOR +// #define CONFIG_JOY2_CURSOR + +// #define CONFIG_PROGRAMMABLE_KEYS + +.const CONFIG_KEYCMD_RUN = @"LOAD\"*\"" + +.const CONFIG_KEYCMD_F1 = @"@" +.const CONFIG_KEYCMD_F2 = @"" +.const CONFIG_KEYCMD_F3 = @"RUN:" +.const CONFIG_KEYCMD_F4 = @"" +.const CONFIG_KEYCMD_F5 = @"LOAD" +.const CONFIG_KEYCMD_F6 = @"" +.const CONFIG_KEYCMD_F7 = @"@$" +.const CONFIG_KEYCMD_F8 = @"" + +.const CONFIG_KEYCMD_HELP = @"LIST" + +.const CONFIG_KEYCMD_F9 = @"REM F9" +.const CONFIG_KEYCMD_F10 = @"REM F10" +.const CONFIG_KEYCMD_F11 = @"REM F11" +.const CONFIG_KEYCMD_F12 = @"REM F12" +.const CONFIG_KEYCMD_F13 = @"REM F13" +.const CONFIG_KEYCMD_F14 = @"REM F14" + + +// Screen editor + +// #define CONFIG_EDIT_STOPQUOTE +// #define CONFIG_EDIT_TABULATORS + + +// Software features + +// #define CONFIG_PANIC_SCREEN +// #define CONFIG_DOS_WEDGE +// #define CONFIG_TAPE_WEDGE +#define CONFIG_BCD_SAFE_INTERRUPTS + + +// Eye candy + +// #define CONFIG_COLORS_BRAND +// #define CONFIG_BANNER_SIMPLE +#define CONFIG_BANNER_FANCY +// #define CONFIG_BANNER_BRAND +// #define CONFIG_SHOW_FEATURES +// #define CONFIG_SHOW_PAL_NTSC + + +// Debug options + +// #define CONFIG_DBG_STUBS_BRK +// #define CONFIG_DBG_PRINTF diff --git a/c64/aliases/,aliases_config.s b/c64/aliases/,aliases_config.s index 60bbddc6..57fb1c9f 100644 --- a/c64/aliases/,aliases_config.s +++ b/c64/aliases/,aliases_config.s @@ -14,6 +14,9 @@ #if CONFIG_PLATFORM_COMMODORE_64 .eval selected++ #endif +#if CONFIG_PLATFORM_COMMANDER_X16 + .eval selected++ +#endif .if (selected != 1) .error "Please select exactly one CONFIG_PLATFORM_* option" } diff --git a/c64/aliases/,aliases_cpu.s b/c64/aliases/,aliases_cpu.s index 922a91bc..b45f73f3 100644 --- a/c64/aliases/,aliases_cpu.s +++ b/c64/aliases/,aliases_cpu.s @@ -34,7 +34,7 @@ .pseudocommand panic code { // If case no panic screen is used, we can skip providing error codes within Kernal -#if CONFIG_PANIC_SCREEN || !SEGMENT_KERNAL +#if CONFIG_PANIC_SCREEN lda code #endif jmp ($E4B7) @@ -117,7 +117,7 @@ .pseudocommand lda_zero // WARNING: do not use within interrupts { -#if HAS_OPCODES_65C02 +#if HAS_OPCODES_65CE02 tba #else lda #$00 diff --git a/c64/aliases/,aliases_rom_basic.s b/c64/aliases/,aliases_rom_basic.s index 67aa954d..89963b51 100644 --- a/c64/aliases/,aliases_rom_basic.s +++ b/c64/aliases/,aliases_rom_basic.s @@ -1,4 +1,15 @@ // BASIC startup vectors + + +#if ROM_LAYOUT_X16 + + .label IBASIC_COLD_START = $C000 + .label IBASIC_WARM_START = $C002 + +#else + .label IBASIC_COLD_START = $A000 .label IBASIC_WARM_START = $A002 + +#endif diff --git a/c64/basic/,stubs/a408.reason.s b/c64/basic/,stubs/a408.reason.s index 8bca5016..00e36030 100644 --- a/c64/basic/,stubs/a408.reason.s +++ b/c64/basic/,stubs/a408.reason.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a453.unknown.s b/c64/basic/,stubs/a453.unknown.s index 02ae9dac..7a54c8b2 100644 --- a/c64/basic/,stubs/a453.unknown.s +++ b/c64/basic/,stubs/a453.unknown.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a483.main.s b/c64/basic/,stubs/a483.main.s index f15fd4d2..9533f2cb 100644 --- a/c64/basic/,stubs/a483.main.s +++ b/c64/basic/,stubs/a483.main.s @@ -1,4 +1,7 @@ -#if ROM_LAYOUT_STD || (ROM_LAYOUT_M65 && SEGMENT_BASIC_0) +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE // // Official BASIC routine, described in: @@ -9,9 +12,5 @@ // CPU registers that has to be preserved (see [RG64]): XXX // - MAIN: STUB_IMPLEMENTATION() - - -#endif // ROM layout diff --git a/c64/basic/,stubs/a57c.chrnch.s b/c64/basic/,stubs/a57c.chrnch.s index b5e3df12..d320dd69 100644 --- a/c64/basic/,stubs/a57c.chrnch.s +++ b/c64/basic/,stubs/a57c.chrnch.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a644.new.s b/c64/basic/,stubs/a644.new.s index 73c8df60..306c8228 100644 --- a/c64/basic/,stubs/a644.new.s +++ b/c64/basic/,stubs/a644.new.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a659.setcharptr.s b/c64/basic/,stubs/a659.setcharptr.s index 64a573a3..17f8cef5 100644 --- a/c64/basic/,stubs/a659.setcharptr.s +++ b/c64/basic/,stubs/a659.setcharptr.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a71a.qplop.s b/c64/basic/,stubs/a71a.qplop.s index 921a807a..03f00cd3 100644 --- a/c64/basic/,stubs/a71a.qplop.s +++ b/c64/basic/,stubs/a71a.qplop.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/a7e4.gone.s b/c64/basic/,stubs/a7e4.gone.s index bfbc4435..33b6e87c 100644 --- a/c64/basic/,stubs/a7e4.gone.s +++ b/c64/basic/,stubs/a7e4.gone.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/ad9e.frmevl.s b/c64/basic/,stubs/ad9e.frmevl.s index 2a246f66..46f275ed 100644 --- a/c64/basic/,stubs/ad9e.frmevl.s +++ b/c64/basic/,stubs/ad9e.frmevl.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs/ae86.eval.s b/c64/basic/,stubs/ae86.eval.s index b8e06255..b790c094 100644 --- a/c64/basic/,stubs/ae86.eval.s +++ b/c64/basic/,stubs/ae86.eval.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s b/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s index 70e6a741..55b66169 100644 --- a/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s +++ b/c64/basic/,stubs_math/a9c4.convert_FAC1_to_INT.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/aabc.print_FAC1.s b/c64/basic/,stubs_math/aabc.print_FAC1.s index 8bcd6a54..163da77b 100644 --- a/c64/basic/,stubs_math/aabc.print_FAC1.s +++ b/c64/basic/,stubs_math/aabc.print_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/af7b.compute_TI.s b/c64/basic/,stubs_math/af7b.compute_TI.s index 835cc59a..0bd1acfc 100644 --- a/c64/basic/,stubs_math/af7b.compute_TI.s +++ b/c64/basic/,stubs_math/af7b.compute_TI.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/af7e.math_stub.s b/c64/basic/,stubs_math/af7e.math_stub.s index 40a32304..c5eacf46 100644 --- a/c64/basic/,stubs_math/af7e.math_stub.s +++ b/c64/basic/,stubs_math/af7e.math_stub.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/af87.math_stub.s b/c64/basic/,stubs_math/af87.math_stub.s index fc4fae09..25746cdc 100644 --- a/c64/basic/,stubs_math/af87.math_stub.s +++ b/c64/basic/,stubs_math/af87.math_stub.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/af9a.compute_ST.s b/c64/basic/,stubs_math/af9a.compute_ST.s index dca181aa..801fa221 100644 --- a/c64/basic/,stubs_math/af9a.compute_ST.s +++ b/c64/basic/,stubs_math/af9a.compute_ST.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b1aa.FACINX.s b/c64/basic/,stubs_math/b1aa.FACINX.s index 9769eeea..11ab5ed0 100644 --- a/c64/basic/,stubs_math/b1aa.FACINX.s +++ b/c64/basic/,stubs_math/b1aa.FACINX.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b391.GIVAYF.s b/c64/basic/,stubs_math/b391.GIVAYF.s index 44650977..982b2262 100644 --- a/c64/basic/,stubs_math/b391.GIVAYF.s +++ b/c64/basic/,stubs_math/b391.GIVAYF.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s b/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s index 49df4eb6..7ec3f99a 100644 --- a/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s +++ b/c64/basic/,stubs_math/b3a2.convert_Y_to_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s b/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s index 8a91c04d..c79f363c 100644 --- a/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s +++ b/c64/basic/,stubs_math/b794.convert_A_to_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b7b5.STRVAL.s b/c64/basic/,stubs_math/b7b5.STRVAL.s index 35ae53d4..f754d8f6 100644 --- a/c64/basic/,stubs_math/b7b5.STRVAL.s +++ b/c64/basic/,stubs_math/b7b5.STRVAL.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s b/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s index eaeee7fc..f38d5a98 100644 --- a/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s +++ b/c64/basic/,stubs_math/b7f7.convert_FAC1_to_ADDR.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b849.add_HALF_FAC1.s b/c64/basic/,stubs_math/b849.add_HALF_FAC1.s index 38f14bc2..deac2795 100644 --- a/c64/basic/,stubs_math/b849.add_HALF_FAC1.s +++ b/c64/basic/,stubs_math/b849.add_HALF_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s index a88305d8..f8aaf267 100644 --- a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s b/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s index aae0f0b2..ceadfe99 100644 --- a/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s +++ b/c64/basic/,stubs_math/b947.inv_FAC1_mantissa.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b983.MULSHF.s b/c64/basic/,stubs_math/b983.MULSHF.s index 37a4fc00..b4389b13 100644 --- a/c64/basic/,stubs_math/b983.MULSHF.s +++ b/c64/basic/,stubs_math/b983.MULSHF.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/b9ea.log_FAC1.s b/c64/basic/,stubs_math/b9ea.log_FAC1.s index 295fdf19..2bc2765c 100644 --- a/c64/basic/,stubs_math/b9ea.log_FAC1.s +++ b/c64/basic/,stubs_math/b9ea.log_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s index bc78e2fb..f6659b85 100644 --- a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s +++ b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/ba59.MLTPLY.s b/c64/basic/,stubs_math/ba59.MLTPLY.s index 369eab72..294cd246 100644 --- a/c64/basic/,stubs_math/ba59.MLTPLY.s +++ b/c64/basic/,stubs_math/ba59.MLTPLY.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bae2.mul10_FAC1.s b/c64/basic/,stubs_math/bae2.mul10_FAC1.s index 8413a242..4d6e570d 100644 --- a/c64/basic/,stubs_math/bae2.mul10_FAC1.s +++ b/c64/basic/,stubs_math/bae2.mul10_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bafe.div10_FAC1_p.s b/c64/basic/,stubs_math/bafe.div10_FAC1_p.s index e3cc5252..0be04ac9 100644 --- a/c64/basic/,stubs_math/bafe.div10_FAC1_p.s +++ b/c64/basic/,stubs_math/bafe.div10_FAC1_p.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s b/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s index 987eed74..03f5b8db 100644 --- a/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s +++ b/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s b/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s index b5e630c5..866ac209 100644 --- a/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s +++ b/c64/basic/,stubs_math/bc2b.sgn_FAC1_A.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc39.sgn_FAC1.s b/c64/basic/,stubs_math/bc39.sgn_FAC1.s index ca081a8e..47af6ee9 100644 --- a/c64/basic/,stubs_math/bc39.sgn_FAC1.s +++ b/c64/basic/,stubs_math/bc39.sgn_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s b/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s index 7b5c3cc9..9187103d 100644 --- a/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s +++ b/c64/basic/,stubs_math/bc3c.convert_A_to_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s b/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s index 9555a39f..b0e1f2e7 100644 --- a/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s +++ b/c64/basic/,stubs_math/bc44.convert_i16_to_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc58.abs_FAC1.s b/c64/basic/,stubs_math/bc58.abs_FAC1.s index 2d4117c6..919f179a 100644 --- a/c64/basic/,stubs_math/bc58.abs_FAC1.s +++ b/c64/basic/,stubs_math/bc58.abs_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc5b.FCOMP.s b/c64/basic/,stubs_math/bc5b.FCOMP.s index c73858b7..e0f00777 100644 --- a/c64/basic/,stubs_math/bc5b.FCOMP.s +++ b/c64/basic/,stubs_math/bc5b.FCOMP.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bc9b.QINT.s b/c64/basic/,stubs_math/bc9b.QINT.s index 8414d0bd..26ba5f71 100644 --- a/c64/basic/,stubs_math/bc9b.QINT.s +++ b/c64/basic/,stubs_math/bc9b.QINT.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bccc.int_FAC1.s b/c64/basic/,stubs_math/bccc.int_FAC1.s index ad25b646..4a7c6d47 100644 --- a/c64/basic/,stubs_math/bccc.int_FAC1.s +++ b/c64/basic/,stubs_math/bccc.int_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bcf3.FIN.s b/c64/basic/,stubs_math/bcf3.FIN.s index 2b85c855..f06e63eb 100644 --- a/c64/basic/,stubs_math/bcf3.FIN.s +++ b/c64/basic/,stubs_math/bcf3.FIN.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bd7e.FINLOG.s b/c64/basic/,stubs_math/bd7e.FINLOG.s index 65a18e9a..998ca32b 100644 --- a/c64/basic/,stubs_math/bd7e.FINLOG.s +++ b/c64/basic/,stubs_math/bd7e.FINLOG.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bddd.FOUT.s b/c64/basic/,stubs_math/bddd.FOUT.s index c0597d05..a9b3b2d8 100644 --- a/c64/basic/,stubs_math/bddd.FOUT.s +++ b/c64/basic/,stubs_math/bddd.FOUT.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bf71.sqr_FAC1.s b/c64/basic/,stubs_math/bf71.sqr_FAC1.s index ca2091c3..ac9a07c3 100644 --- a/c64/basic/,stubs_math/bf71.sqr_FAC1.s +++ b/c64/basic/,stubs_math/bf71.sqr_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bf74.sqr_FAC2.s b/c64/basic/,stubs_math/bf74.sqr_FAC2.s index ab99c98f..a0b8a412 100644 --- a/c64/basic/,stubs_math/bf74.sqr_FAC2.s +++ b/c64/basic/,stubs_math/bf74.sqr_FAC2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bf78.FPWR.s b/c64/basic/,stubs_math/bf78.FPWR.s index 42226482..3225ae9c 100644 --- a/c64/basic/,stubs_math/bf78.FPWR.s +++ b/c64/basic/,stubs_math/bf78.FPWR.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bf7b.FPWRT.s b/c64/basic/,stubs_math/bf7b.FPWRT.s index 5c58e9f1..1bc6264a 100644 --- a/c64/basic/,stubs_math/bf7b.FPWRT.s +++ b/c64/basic/,stubs_math/bf7b.FPWRT.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/,stubs_math/bfed.exp_FAC1.s b/c64/basic/,stubs_math/bfed.exp_FAC1.s index 9e392ad8..296a58a3 100644 --- a/c64/basic/,stubs_math/bfed.exp_FAC1.s +++ b/c64/basic/,stubs_math/bfed.exp_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/a533.linkprg.s b/c64/basic/a533.linkprg.s index 4db59db1..f272bd30 100644 --- a/c64/basic/a533.linkprg.s +++ b/c64/basic/a533.linkprg.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/a68e.runc.s b/c64/basic/a68e.runc.s index f0a8aeb1..bda66edc 100644 --- a/c64/basic/a68e.runc.s +++ b/c64/basic/a68e.runc.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/a7ae.newstt.s b/c64/basic/a7ae.newstt.s index 79aed4d6..069a1276 100644 --- a/c64/basic/a7ae.newstt.s +++ b/c64/basic/a7ae.newstt.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/ab1e.strout.s b/c64/basic/ab1e.strout.s index 0317550a..d067e9e1 100644 --- a/c64/basic/ab1e.strout.s +++ b/c64/basic/ab1e.strout.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/bdcd.linprt.s b/c64/basic/bdcd.linprt.s index 284b626e..5ab2fd47 100644 --- a/c64/basic/bdcd.linprt.s +++ b/c64/basic/bdcd.linprt.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/banking/dummy.s b/c64/basic/board_m65/mega65_dummy.s similarity index 60% rename from c64/basic/banking/dummy.s rename to c64/basic/board_m65/mega65_dummy.s index eea566c2..338a1c16 100644 --- a/c64/basic/banking/dummy.s +++ b/c64/basic/board_m65/mega65_dummy.s @@ -2,6 +2,6 @@ // #LAYOUT# * * #IGNORE -// Dummy, just to have anyything in segment 1 +// Dummy, just to have anything in segment 1 brk diff --git a/c64/basic/board_x16/cx16_dummy.s b/c64/basic/board_x16/cx16_dummy.s new file mode 100644 index 00000000..e1558df9 --- /dev/null +++ b/c64/basic/board_x16/cx16_dummy.s @@ -0,0 +1,7 @@ +// #LAYOUT# X16 BASIC_1 #TAKE +// #LAYOUT# * * #IGNORE + + +// Dummy, just to have anything in segment 1 + + brk diff --git a/c64/basic/c000.skip_gap.s b/c64/basic/c000.skip_gap.s index 9d256aeb..a8d678e6 100644 --- a/c64/basic/c000.skip_gap.s +++ b/c64/basic/c000.skip_gap.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/init/a000.cold_start_vector.s b/c64/basic/init/a000.cold_start_vector.s index 067b0f64..ef12f257 100644 --- a/c64/basic/init/a000.cold_start_vector.s +++ b/c64/basic/init/a000.cold_start_vector.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/init/a002.warm_start_vector.s b/c64/basic/init/a002.warm_start_vector.s index 411e17a5..717c4b2b 100644 --- a/c64/basic/init/a002.warm_start_vector.s +++ b/c64/basic/init/a002.warm_start_vector.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/b850.sub_MEM_FAC1.s b/c64/basic/math/b850.sub_MEM_FAC1.s index a5f15869..72281c92 100644 --- a/c64/basic/math/b850.sub_MEM_FAC1.s +++ b/c64/basic/math/b850.sub_MEM_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/b853.sub_FAC2_FAC1.s b/c64/basic/math/b853.sub_FAC2_FAC1.s index 49f699e9..e54a85a9 100644 --- a/c64/basic/math/b853.sub_FAC2_FAC1.s +++ b/c64/basic/math/b853.sub_FAC2_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/b862.add_align_exponent.jmp.s b/c64/basic/math/b862.add_align_exponent.jmp.s index bcddf0ba..03fef8c3 100644 --- a/c64/basic/math/b862.add_align_exponent.jmp.s +++ b/c64/basic/math/b862.add_align_exponent.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/b867.add_MEM_FAC1.s b/c64/basic/math/b867.add_MEM_FAC1.s index 9ed42325..1d948ee0 100644 --- a/c64/basic/math/b867.add_MEM_FAC1.s +++ b/c64/basic/math/b867.add_MEM_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/b8fe.normal_FAC1.jmp.s b/c64/basic/math/b8fe.normal_FAC1.jmp.s index a9fd1d5c..e40972f8 100644 --- a/c64/basic/math/b8fe.normal_FAC1.jmp.s +++ b/c64/basic/math/b8fe.normal_FAC1.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/ba28.mul_MEM_FAC1.s b/c64/basic/math/ba28.mul_MEM_FAC1.s index 3a5c5f08..02a35b91 100644 --- a/c64/basic/math/ba28.mul_MEM_FAC1.s +++ b/c64/basic/math/ba28.mul_MEM_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s b/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s index 2e2bdffc..d556073a 100644 --- a/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s +++ b/c64/basic/math/ba8c.mov_MEM_FAC2.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bb0f.div_MEM_FAC1.s b/c64/basic/math/bb0f.div_MEM_FAC1.s index 37fc4c6a..2863958a 100644 --- a/c64/basic/math/bb0f.div_MEM_FAC1.s +++ b/c64/basic/math/bb0f.div_MEM_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s b/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s index 71b6fe4a..21e9f9ca 100644 --- a/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s +++ b/c64/basic/math/bba2.mov_MEM_FAC1.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s index 9fd4c393..a3651fd4 100644 --- a/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s +++ b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bbca.mov_r_FAC1_TMP1.s b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s index 1b3ed69c..d9993d30 100644 --- a/c64/basic/math/bbca.mov_r_FAC1_TMP1.s +++ b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bbd0.mov_r_FAC1_VAR.s b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s index 2d34f663..59ac4b18 100644 --- a/c64/basic/math/bbd0.mov_r_FAC1_VAR.s +++ b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bbd4.mov_r_FAC1_MEM.s b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s index 26f898bd..8bf3182d 100644 --- a/c64/basic/math/bbd4.mov_r_FAC1_MEM.s +++ b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bbfc.mov_FAC2_FAC1.s b/c64/basic/math/bbfc.mov_FAC2_FAC1.s index 509a911a..a59de960 100644 --- a/c64/basic/math/bbfc.mov_FAC2_FAC1.s +++ b/c64/basic/math/bbfc.mov_FAC2_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s index 084d7e16..edf6e9cd 100644 --- a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s +++ b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s b/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s index dde35453..6cb71a8d 100644 --- a/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s +++ b/c64/basic/math/bc0f.mov_FAC1_FAC2.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bc1b.round_FAC1.jmp.s b/c64/basic/math/bc1b.round_FAC1.jmp.s index 1c04b38e..6658d65e 100644 --- a/c64/basic/math/bc1b.round_FAC1.jmp.s +++ b/c64/basic/math/bc1b.round_FAC1.jmp.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math/bfb4.toggle_sign_FAC1.s b/c64/basic/math/bfb4.toggle_sign_FAC1.s index bfa61cc5..c73ed745 100644 --- a/c64/basic/math/bfb4.toggle_sign_FAC1.s +++ b/c64/basic/math/bfb4.toggle_sign_FAC1.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/aea8.const_PI.s b/c64/basic/math_consts/aea8.const_PI.s index c5d79808..d86c1687 100644 --- a/c64/basic/math_consts/aea8.const_PI.s +++ b/c64/basic/math_consts/aea8.const_PI.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b1a5.const_NEG_32768.s b/c64/basic/math_consts/b1a5.const_NEG_32768.s index 2319be90..c45694fa 100644 --- a/c64/basic/math_consts/b1a5.const_NEG_32768.s +++ b/c64/basic/math_consts/b1a5.const_NEG_32768.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b9bc.const_ONE.s b/c64/basic/math_consts/b9bc.const_ONE.s index 63e4eab9..38997280 100644 --- a/c64/basic/math_consts/b9bc.const_ONE.s +++ b/c64/basic/math_consts/b9bc.const_ONE.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b9d6.const_INV_SQR_2.s b/c64/basic/math_consts/b9d6.const_INV_SQR_2.s index 2bd0db76..e3733683 100644 --- a/c64/basic/math_consts/b9d6.const_INV_SQR_2.s +++ b/c64/basic/math_consts/b9d6.const_INV_SQR_2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b9db.const_SQR_2.s b/c64/basic/math_consts/b9db.const_SQR_2.s index 7a4d3def..ab9d0a51 100644 --- a/c64/basic/math_consts/b9db.const_SQR_2.s +++ b/c64/basic/math_consts/b9db.const_SQR_2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b9e0.const_NEG_HALF.s b/c64/basic/math_consts/b9e0.const_NEG_HALF.s index 08ad27d2..0227e546 100644 --- a/c64/basic/math_consts/b9e0.const_NEG_HALF.s +++ b/c64/basic/math_consts/b9e0.const_NEG_HALF.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/b9e5.const_LOG_2.s b/c64/basic/math_consts/b9e5.const_LOG_2.s index 1d9286a7..559d1861 100644 --- a/c64/basic/math_consts/b9e5.const_LOG_2.s +++ b/c64/basic/math_consts/b9e5.const_LOG_2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/baf9.const_TEN.s b/c64/basic/math_consts/baf9.const_TEN.s index 65c8b61b..e2610722 100644 --- a/c64/basic/math_consts/baf9.const_TEN.s +++ b/c64/basic/math_consts/baf9.const_TEN.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/bf11.const_HALF.s b/c64/basic/math_consts/bf11.const_HALF.s index 8574ee8b..15e1f801 100644 --- a/c64/basic/math_consts/bf11.const_HALF.s +++ b/c64/basic/math_consts/bf11.const_HALF.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/bfbf.const_INV_LOG_2.s b/c64/basic/math_consts/bfbf.const_INV_LOG_2.s index 78cf4362..07d97253 100644 --- a/c64/basic/math_consts/bfbf.const_INV_LOG_2.s +++ b/c64/basic/math_consts/bfbf.const_INV_LOG_2.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/math_consts/bfe8.const_ONE.s b/c64/basic/math_consts/bfe8.const_ONE.s index 1f7dab4c..bea746ee 100644 --- a/c64/basic/math_consts/bfe8.const_ONE.s +++ b/c64/basic/math_consts/bfe8.const_ONE.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/rom_revision/a004.identifier.s b/c64/basic/rom_revision/a004.identifier.s index 2edea486..5d780247 100644 --- a/c64/basic/rom_revision/a004.identifier.s +++ b/c64/basic/rom_revision/a004.identifier.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/basic/rom_revision/bf52.rom_revision_basic.s b/c64/basic/rom_revision/bf52.rom_revision_basic.s index 91438dac..c3920eea 100644 --- a/c64/basic/rom_revision/bf52.rom_revision_basic.s +++ b/c64/basic/rom_revision/bf52.rom_revision_basic.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 // #LAYOUT# * BASIC_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/programmable_keys.s b/c64/kernal/assets/programmable_keys.s similarity index 100% rename from c64/kernal/keyboard/programmable_keys.s rename to c64/kernal/assets/programmable_keys.s diff --git a/c64/kernal/banking/4000.interop b/c64/kernal/board_m65/4000.interop similarity index 100% rename from c64/kernal/banking/4000.interop rename to c64/kernal/board_m65/4000.interop diff --git a/c64/kernal/banking/4000.mega65_vectable_kernal_1.s b/c64/kernal/board_m65/4000.mega65_vectable_kernal_1.s similarity index 100% rename from c64/kernal/banking/4000.mega65_vectable_kernal_1.s rename to c64/kernal/board_m65/4000.mega65_vectable_kernal_1.s diff --git a/c64/kernal/banking/mega65_imports.s b/c64/kernal/board_m65/mega65_imports.s similarity index 100% rename from c64/kernal/banking/mega65_imports.s rename to c64/kernal/board_m65/mega65_imports.s diff --git a/c64/kernal/banking/mega65_map_helpers.s b/c64/kernal/board_m65/mega65_map_helpers.s similarity index 100% rename from c64/kernal/banking/mega65_map_helpers.s rename to c64/kernal/board_m65/mega65_map_helpers.s diff --git a/c64/kernal/banking/mega65_proxies.s b/c64/kernal/board_m65/mega65_proxies.s similarity index 100% rename from c64/kernal/banking/mega65_proxies.s rename to c64/kernal/board_m65/mega65_proxies.s diff --git a/c64/kernal/banking/mega65_redirect_load_tape.s b/c64/kernal/board_m65/mega65_redirect_load_tape.s similarity index 100% rename from c64/kernal/banking/mega65_redirect_load_tape.s rename to c64/kernal/board_m65/mega65_redirect_load_tape.s diff --git a/c64/kernal/tape/tape_normal_byte_store_mega65.s b/c64/kernal/board_m65/mega65_tape_normal_byte_store.s similarity index 100% rename from c64/kernal/tape/tape_normal_byte_store_mega65.s rename to c64/kernal/board_m65/mega65_tape_normal_byte_store.s diff --git a/c64/kernal/board_x16/cx16_dummy.s b/c64/kernal/board_x16/cx16_dummy.s new file mode 100644 index 00000000..b25fa5cd --- /dev/null +++ b/c64/kernal/board_x16/cx16_dummy.s @@ -0,0 +1,7 @@ +// #LAYOUT# X16 KERNAL_1 #TAKE +// #LAYOUT# * * #IGNORE + + +// Dummy, just to have anything in segment 1 + + brk diff --git a/c64/kernal/board_x16/cx16_stubs.s b/c64/kernal/board_x16/cx16_stubs.s new file mode 100644 index 00000000..da530dd6 --- /dev/null +++ b/c64/kernal/board_x16/cx16_stubs.s @@ -0,0 +1,44 @@ +// #LAYOUT# X16 KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Stubs for Commander X16 support + + +scnkey_set_keytab: + STUB_IMPLEMENTATION() + +clear_screen: + STUB_IMPLEMENTATION() + +setup_vicii: + STUB_IMPLEMENTATION() + +cursor_blink: + STUB_IMPLEMENTATION() + +chrin_keyboard: + STUB_IMPLEMENTATION() + +chrout_screen: + STUB_IMPLEMENTATION() + +IOINIT: + STUB_IMPLEMENTATION() + +SCNKEY: + STUB_IMPLEMENTATION() + +SCREEN: + STUB_IMPLEMENTATION() + +screen_calculate_pointers: + STUB_IMPLEMENTATION() + +setup_pal_ntsc: + STUB_IMPLEMENTATION() + +wait_x_bars: + STUB_IMPLEMENTATION() + +udtim_keyboard: + STUB_IMPLEMENTATION() diff --git a/c64/kernal/iec/iec_wait1ms.s b/c64/kernal/iec/iec_wait1ms.s index 2b1452fd..f011c292 100644 --- a/c64/kernal/iec/iec_wait1ms.s +++ b/c64/kernal/iec/iec_wait1ms.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/init/e5a0.setup_vicii.s b/c64/kernal/init/e5a0.setup_vicii.s index 28cc6bf9..93b54949 100644 --- a/c64/kernal/init/e5a0.setup_vicii.s +++ b/c64/kernal/init/e5a0.setup_vicii.s @@ -1,6 +1,7 @@ // #LAYOUT# STD * #TAKE // #LAYOUT# M65 KERNAL_0 #TAKE // #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/init/fce2.hw_entry_reset.s b/c64/kernal/init/fce2.hw_entry_reset.s index dbe2c942..474668f2 100644 --- a/c64/kernal/init/fce2.hw_entry_reset.s +++ b/c64/kernal/init/fce2.hw_entry_reset.s @@ -29,9 +29,12 @@ hw_entry_reset: bne !+ jmp (ICART_COLD_START) !: + +#if CONFIG_PLATFORM_COMMODORE_64 // Disable the screen (and set 40 columns) to prevent visual glitches later ldx #$28 stx VIC_SCROLX +#endif // Initialising IO is obviously required. Also indicated by c64 prg p269. jsr JIOINIT diff --git a/c64/kernal/init/fd50.ramtas.s b/c64/kernal/init/fd50.ramtas.s index 3ef9461b..412797bc 100644 --- a/c64/kernal/init/fd50.ramtas.s +++ b/c64/kernal/init/fd50.ramtas.s @@ -1,6 +1,7 @@ // #LAYOUT# STD * #TAKE // #LAYOUT# M65 KERNAL_0 #TAKE // #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT +// #LAYOUT# X16 KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/init/fda3.ioinit.s b/c64/kernal/init/fda3.ioinit.s index 72582f05..35d07223 100644 --- a/c64/kernal/init/fda3.ioinit.s +++ b/c64/kernal/init/fda3.ioinit.s @@ -1,6 +1,7 @@ // #LAYOUT# STD * #TAKE // #LAYOUT# M65 KERNAL_0 #TAKE // #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * * #IGNORE // diff --git a/c64/kernal/init/setup_pal_ntsc.s b/c64/kernal/init/setup_pal_ntsc.s index ebc22052..52845204 100644 --- a/c64/kernal/init/setup_pal_ntsc.s +++ b/c64/kernal/init/setup_pal_ntsc.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/interrupts/ea31.default_irq_handler.s b/c64/kernal/interrupts/ea31.default_irq_handler.s index 671839a3..6793302b 100644 --- a/c64/kernal/interrupts/ea31.default_irq_handler.s +++ b/c64/kernal/interrupts/ea31.default_irq_handler.s @@ -44,5 +44,13 @@ default_irq_handler_end_tape: #endif // CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO +#if CONFIG_PLATFORM_COMMODORE_64 + // Acknowledge CIA interrupt and return jmp clear_cia1_interrupt_flag_and_return_from_interrupt + +#else + + jmp return_from_interrupt + +#endif diff --git a/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s b/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s index 6ba7c968..6d72292d 100644 --- a/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s +++ b/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/interrupts/fe66.default_brk_handler.s b/c64/kernal/interrupts/fe66.default_brk_handler.s index bcec92a5..668462f3 100644 --- a/c64/kernal/interrupts/fe66.default_brk_handler.s +++ b/c64/kernal/interrupts/fe66.default_brk_handler.s @@ -9,9 +9,13 @@ default_brk_handler: sei // disable IRQs, to be sure they wont interfere +#if CONFIG_PLATFORM_COMMODORE_64 + ldx #$00 sta VIC_SCROLX // turn the display off - we want as little screen artifacts as possible +#endif + cld // make sure this dangerous flag is disabled jsr JRESTOR diff --git a/c64/kernal/screen/e50a.interop b/c64/kernal/iostack/e50a.interop similarity index 100% rename from c64/kernal/screen/e50a.interop rename to c64/kernal/iostack/e50a.interop diff --git a/c64/kernal/screen/e50a.plot.s b/c64/kernal/iostack/e50a.plot.s similarity index 100% rename from c64/kernal/screen/e50a.plot.s rename to c64/kernal/iostack/e50a.plot.s diff --git a/c64/kernal/keyboard/pop_keyboard_buffer.s b/c64/kernal/iostack/pop_keyboard_buffer.s similarity index 100% rename from c64/kernal/keyboard/pop_keyboard_buffer.s rename to c64/kernal/iostack/pop_keyboard_buffer.s diff --git a/c64/kernal/keyboard/chrin_keyboard.s b/c64/kernal/keyboard/chrin_keyboard.s index afdf4515..6645a9b8 100644 --- a/c64/kernal/keyboard/chrin_keyboard.s +++ b/c64/kernal/keyboard/chrin_keyboard.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix.s b/c64/kernal/keyboard/kb_matrix.s index 57458aae..e194bd95 100644 --- a/c64/kernal/keyboard/kb_matrix.s +++ b/c64/kernal/keyboard/kb_matrix.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_128.s b/c64/kernal/keyboard/kb_matrix_128.s index 9009f8b9..d6323ba6 100644 --- a/c64/kernal/keyboard/kb_matrix_128.s +++ b/c64/kernal/keyboard/kb_matrix_128.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_65.s b/c64/kernal/keyboard/kb_matrix_65.s index eb50d79b..a7cd89f5 100644 --- a/c64/kernal/keyboard/kb_matrix_65.s +++ b/c64/kernal/keyboard/kb_matrix_65.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_alwaysrepeat.s b/c64/kernal/keyboard/kb_matrix_alwaysrepeat.s index b49d4943..9ccf1b16 100644 --- a/c64/kernal/keyboard/kb_matrix_alwaysrepeat.s +++ b/c64/kernal/keyboard/kb_matrix_alwaysrepeat.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_bucky.s b/c64/kernal/keyboard/kb_matrix_bucky.s index 089ffaef..028721b0 100644 --- a/c64/kernal/keyboard/kb_matrix_bucky.s +++ b/c64/kernal/keyboard/kb_matrix_bucky.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_bucky_filter.s b/c64/kernal/keyboard/kb_matrix_bucky_filter.s index 0c693c5d..70d7251f 100644 --- a/c64/kernal/keyboard/kb_matrix_bucky_filter.s +++ b/c64/kernal/keyboard/kb_matrix_bucky_filter.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_joy.s b/c64/kernal/keyboard/kb_matrix_joy.s index d19644f1..754c341f 100644 --- a/c64/kernal/keyboard/kb_matrix_joy.s +++ b/c64/kernal/keyboard/kb_matrix_joy.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_lookup.s b/c64/kernal/keyboard/kb_matrix_lookup.s index 1d9715fc..bb82cf2c 100644 --- a/c64/kernal/keyboard/kb_matrix_lookup.s +++ b/c64/kernal/keyboard/kb_matrix_lookup.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_lookup_legacy.s b/c64/kernal/keyboard/kb_matrix_lookup_legacy.s index b628921f..da4df653 100644 --- a/c64/kernal/keyboard/kb_matrix_lookup_legacy.s +++ b/c64/kernal/keyboard/kb_matrix_lookup_legacy.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_row_keys.s b/c64/kernal/keyboard/kb_matrix_row_keys.s index 21bab4f5..ce225e80 100644 --- a/c64/kernal/keyboard/kb_matrix_row_keys.s +++ b/c64/kernal/keyboard/kb_matrix_row_keys.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/kb_matrix_row_offsets.s b/c64/kernal/keyboard/kb_matrix_row_offsets.s index 8b0b7d5a..314a0852 100644 --- a/c64/kernal/keyboard/kb_matrix_row_offsets.s +++ b/c64/kernal/keyboard/kb_matrix_row_offsets.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/keyboard_disconnect.s b/c64/kernal/keyboard/keyboard_disconnect.s index 5fb2bf73..98c0150b 100644 --- a/c64/kernal/keyboard/keyboard_disconnect.s +++ b/c64/kernal/keyboard/keyboard_disconnect.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/scnkey.s b/c64/kernal/keyboard/scnkey.s index 003b38e5..12161598 100644 --- a/c64/kernal/keyboard/scnkey.s +++ b/c64/kernal/keyboard/scnkey.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/scnkey_128.s b/c64/kernal/keyboard/scnkey_128.s index 48945214..fd00cddc 100644 --- a/c64/kernal/keyboard/scnkey_128.s +++ b/c64/kernal/keyboard/scnkey_128.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/scnkey_65.s b/c64/kernal/keyboard/scnkey_65.s index 34584b72..8518c837 100644 --- a/c64/kernal/keyboard/scnkey_65.s +++ b/c64/kernal/keyboard/scnkey_65.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/scnkey_legacy.s b/c64/kernal/keyboard/scnkey_legacy.s index 42dae86f..d5ab27d2 100644 --- a/c64/kernal/keyboard/scnkey_legacy.s +++ b/c64/kernal/keyboard/scnkey_legacy.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/scnkey_set_keytab.s b/c64/kernal/keyboard/scnkey_set_keytab.s index c1da0a66..77ad45aa 100644 --- a/c64/kernal/keyboard/scnkey_set_keytab.s +++ b/c64/kernal/keyboard/scnkey_set_keytab.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/keyboard/udtim_keyboard.s b/c64/kernal/keyboard/udtim_keyboard.s index 35d6724a..d1c8c74e 100644 --- a/c64/kernal/keyboard/udtim_keyboard.s +++ b/c64/kernal/keyboard/udtim_keyboard.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen.s b/c64/kernal/screen/chrout_screen.s index 356816d0..14c583b5 100644 --- a/c64/kernal/screen/chrout_screen.s +++ b/c64/kernal/screen/chrout_screen.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_clr.s b/c64/kernal/screen/chrout_screen_clr.s index 7da09ca6..e2860ce5 100644 --- a/c64/kernal/screen/chrout_screen_clr.s +++ b/c64/kernal/screen/chrout_screen_clr.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_control.s b/c64/kernal/screen/chrout_screen_control.s index 7f93c521..8100db55 100644 --- a/c64/kernal/screen/chrout_screen_control.s +++ b/c64/kernal/screen/chrout_screen_control.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_crsr.s b/c64/kernal/screen/chrout_screen_crsr.s index cb276f41..819c8a9a 100644 --- a/c64/kernal/screen/chrout_screen_crsr.s +++ b/c64/kernal/screen/chrout_screen_crsr.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_del.s b/c64/kernal/screen/chrout_screen_del.s index 5cfaaa07..96b8c46b 100644 --- a/c64/kernal/screen/chrout_screen_del.s +++ b/c64/kernal/screen/chrout_screen_del.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_gfxtxt.s b/c64/kernal/screen/chrout_screen_gfxtxt.s index 9f326e43..04d73c04 100644 --- a/c64/kernal/screen/chrout_screen_gfxtxt.s +++ b/c64/kernal/screen/chrout_screen_gfxtxt.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_home.s b/c64/kernal/screen/chrout_screen_home.s index 4f0e3d05..353429f4 100644 --- a/c64/kernal/screen/chrout_screen_home.s +++ b/c64/kernal/screen/chrout_screen_home.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_ins.s b/c64/kernal/screen/chrout_screen_ins.s index 74be6b2a..61ac4211 100644 --- a/c64/kernal/screen/chrout_screen_ins.s +++ b/c64/kernal/screen/chrout_screen_ins.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_jumptable_codes.s b/c64/kernal/screen/chrout_screen_jumptable_codes.s index a3dc700d..5c959dcd 100644 --- a/c64/kernal/screen/chrout_screen_jumptable_codes.s +++ b/c64/kernal/screen/chrout_screen_jumptable_codes.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_quote.s b/c64/kernal/screen/chrout_screen_quote.s index 8bbe2440..245450ab 100644 --- a/c64/kernal/screen/chrout_screen_quote.s +++ b/c64/kernal/screen/chrout_screen_quote.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_return.s b/c64/kernal/screen/chrout_screen_return.s index 4148dda6..5f42ae14 100644 --- a/c64/kernal/screen/chrout_screen_return.s +++ b/c64/kernal/screen/chrout_screen_return.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_rvs.s b/c64/kernal/screen/chrout_screen_rvs.s index 3cb679ae..47dce95f 100644 --- a/c64/kernal/screen/chrout_screen_rvs.s +++ b/c64/kernal/screen/chrout_screen_rvs.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_shift_onoff.s b/c64/kernal/screen/chrout_screen_shift_onoff.s index 7ecbbe2a..24369ada 100644 --- a/c64/kernal/screen/chrout_screen_shift_onoff.s +++ b/c64/kernal/screen/chrout_screen_shift_onoff.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_stop.s b/c64/kernal/screen/chrout_screen_stop.s index 3c638032..d44654f6 100644 --- a/c64/kernal/screen/chrout_screen_stop.s +++ b/c64/kernal/screen/chrout_screen_stop.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/chrout_screen_tab.s b/c64/kernal/screen/chrout_screen_tab.s index 13634dc9..6ca12662 100644 --- a/c64/kernal/screen/chrout_screen_tab.s +++ b/c64/kernal/screen/chrout_screen_tab.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/cursor.s b/c64/kernal/screen/cursor.s index 15b460d2..7021133a 100644 --- a/c64/kernal/screen/cursor.s +++ b/c64/kernal/screen/cursor.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/cursor_enable.s b/c64/kernal/screen/cursor_enable.s index 155f28b4..d5322360 100644 --- a/c64/kernal/screen/cursor_enable.s +++ b/c64/kernal/screen/cursor_enable.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/cursor_show.s b/c64/kernal/screen/cursor_show.s index e96987aa..d700679f 100644 --- a/c64/kernal/screen/cursor_show.s +++ b/c64/kernal/screen/cursor_show.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/e544.clear_screen.s b/c64/kernal/screen/e544.clear_screen.s index e80029ca..7c241c09 100644 --- a/c64/kernal/screen/e544.clear_screen.s +++ b/c64/kernal/screen/e544.clear_screen.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/e566.cursor_home.s b/c64/kernal/screen/e566.cursor_home.s index 0e22fe78..782f5189 100644 --- a/c64/kernal/screen/e566.cursor_home.s +++ b/c64/kernal/screen/e566.cursor_home.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/e56c.screen_calculate_pointers.s b/c64/kernal/screen/e56c.screen_calculate_pointers.s index 591862c6..cb4194b9 100644 --- a/c64/kernal/screen/e56c.screen_calculate_pointers.s +++ b/c64/kernal/screen/e56c.screen_calculate_pointers.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/e8ea.screen_scroll_up.s b/c64/kernal/screen/e8ea.screen_scroll_up.s index fb3f262e..2b11f352 100644 --- a/c64/kernal/screen/e8ea.screen_scroll_up.s +++ b/c64/kernal/screen/e8ea.screen_scroll_up.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/e9ff.screen_clear_line.s b/c64/kernal/screen/e9ff.screen_clear_line.s index 6dc1f915..4611a575 100644 --- a/c64/kernal/screen/e9ff.screen_clear_line.s +++ b/c64/kernal/screen/e9ff.screen_clear_line.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen.s b/c64/kernal/screen/screen.s index 2d3611df..6b98bdb3 100644 --- a/c64/kernal/screen/screen.s +++ b/c64/kernal/screen/screen.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_advance_to_next_line.s b/c64/kernal/screen/screen_advance_to_next_line.s index c711e292..eb02bc8b 100644 --- a/c64/kernal/screen/screen_advance_to_next_line.s +++ b/c64/kernal/screen/screen_advance_to_next_line.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_calculate_pnt_user.s b/c64/kernal/screen/screen_calculate_pnt_user.s index ce477aa3..4fc409fa 100644 --- a/c64/kernal/screen/screen_calculate_pnt_user.s +++ b/c64/kernal/screen/screen_calculate_pnt_user.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_calculate_pntr_lnmx.s b/c64/kernal/screen/screen_calculate_pntr_lnmx.s index 7b4e7f5f..b024c448 100644 --- a/c64/kernal/screen/screen_calculate_pntr_lnmx.s +++ b/c64/kernal/screen/screen_calculate_pntr_lnmx.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_check_space_ends_line.s b/c64/kernal/screen/screen_check_space_ends_line.s index a482dc9e..7c1243b5 100644 --- a/c64/kernal/screen/screen_check_space_ends_line.s +++ b/c64/kernal/screen/screen_check_space_ends_line.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_code_to_petscii.s b/c64/kernal/screen/screen_code_to_petscii.s index 7a76aae3..898f2883 100644 --- a/c64/kernal/screen/screen_code_to_petscii.s +++ b/c64/kernal/screen/screen_code_to_petscii.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_get_cliped_pntr.s b/c64/kernal/screen/screen_get_cliped_pntr.s index 761ffd92..355499fb 100644 --- a/c64/kernal/screen/screen_get_cliped_pntr.s +++ b/c64/kernal/screen/screen_get_cliped_pntr.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_get_logical_line_end_ptr.s b/c64/kernal/screen/screen_get_logical_line_end_ptr.s index e54bdd3d..b2bbc293 100644 --- a/c64/kernal/screen/screen_get_logical_line_end_ptr.s +++ b/c64/kernal/screen/screen_get_logical_line_end_ptr.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_grow_logical_line.s b/c64/kernal/screen/screen_grow_logical_line.s index 92654151..96ecac98 100644 --- a/c64/kernal/screen/screen_grow_logical_line.s +++ b/c64/kernal/screen/screen_grow_logical_line.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_off.s b/c64/kernal/screen/screen_off.s index 154ce86f..f7ef6d62 100644 --- a/c64/kernal/screen/screen_off.s +++ b/c64/kernal/screen/screen_off.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_on.s b/c64/kernal/screen/screen_on.s index 24e70a1b..6d49d4a4 100644 --- a/c64/kernal/screen/screen_on.s +++ b/c64/kernal/screen/screen_on.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_preserve_sal_eal.s b/c64/kernal/screen/screen_preserve_sal_eal.s index e4f7f55f..a576cbab 100644 --- a/c64/kernal/screen/screen_preserve_sal_eal.s +++ b/c64/kernal/screen/screen_preserve_sal_eal.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/screen/screen_restore_sal_eal.s b/c64/kernal/screen/screen_restore_sal_eal.s index fd8648c5..6f10b390 100644 --- a/c64/kernal/screen/screen_restore_sal_eal.s +++ b/c64/kernal/screen/screen_restore_sal_eal.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/doc/Development.md b/doc/Development.md index 86c3160d..68cd49c6 100644 --- a/doc/Development.md +++ b/doc/Development.md @@ -85,10 +85,11 @@ List of the most important make targets: ### Code segments and ROM layouts -Currently there are 2 ROM layouts defined: +Currently there are 3 ROM layouts defined: - `STD` - with 2 code segments: `BASIC` (`$A000-$E4D2`, where `$C000-$DFFF` is a skip-gap for RAM and I/O area) and `KERNAL` (`$E4D3 - $FFFF`) - `M65` - where `BASIC` becames `BASIC_0` and `KERNAL` becames `KERNAL_0`, additional segments might be added to the build system in the future; at the moment of writing this document additional 8KB of ROM is defined as `BASIC_1` segment and additional 8KB of ROM is defined as `KERNAL_1` segment +- `X16` - memory layout for the Commander X16 machine To check for current ROM layout or code segment use KickAssembler preprocessor defines, like `ROM_LAYOUT_STD`, `ROM_LAYOUT_M65`, `SEGMENT_BASIC`, `SEGMENT_KERNAL_1`. @@ -107,7 +108,7 @@ File name of the fixed location routine adheres to the scheme: `addr.name.s`, wh For handling different ROM layouts, our build tool provides support for pragma-like comments, in the form: ``` -// #LAYOUT# +// #LAYOUT# ``` where: @@ -117,11 +118,12 @@ where: - `` - `KERNAL`, `BASIC`, `KERNAL_0`, `KERNAL_1`, etc., asterisk symbol can be used to match any segment - `` - what to do when layout and segment match: -| action | description | -| :------------ | :-------------------------------------------- | -| `#IGNORE` | ignore the file completely | -| `#TAKE` | compile the file normally | -| `#TAKE-FLOAT` | compile the file, but force it to be floating | +| action | description | +| :------------- | :----------------------------------------------------------------- | +| `#IGNORE` | ignore the file completely | +| `#TAKE` | compile the file normally | +| `#TAKE-FLOAT` | compile the file, but force it to be floating | +| `#TAKE-OFFSET` | shifts the fixed-location address by hex offset given as parameter | The first match counts, all the remaining ones are dropped. Examples: diff --git a/tools/build_segment.cc b/tools/build_segment.cc index 643da112..422819ef 100644 --- a/tools/build_segment.cc +++ b/tools/build_segment.cc @@ -91,8 +91,8 @@ public: std::vector content; std::string label; - int startAddr; // for fixed (non-floating) routines only - int codeLength; // for both fixed and floating routines + int startAddr; // for fixed (non-floating) routines only + int codeLength; // for both fixed and floating routines int testAddrStart; // start address during test run int testAddrEnd; // end address during test run @@ -170,8 +170,8 @@ void parseCommandLine(int argc, char **argv) case 's': CMD_segName = optarg; break; case 'i': CMD_segInfo = optarg; break; case 'r': CMD_romLayout = optarg; break; - case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break; - case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break; + case 'l': CMD_loAddress = strtol(optarg, nullptr, 16); break; + case 'h': CMD_hiAddress = strtol(optarg, nullptr, 16); break; default: printUsage(); ERROR(); } } @@ -692,6 +692,11 @@ bool SourceFile::preprocessLine(const std::string &line) { floating = true; } + else if (iter->compare("#TAKE-OFFSET") == 0) + { + if (++iter == tokens.end()) ERROR("syntax error, missing parameter for '#TAKE-OFFSET'"); + startAddr += strtol(iter->c_str(), nullptr, 16); + } else if (iter->compare("#TAKE") != 0) { ERROR(std::string("syntax error, unsupported action '") + token + "' in '#LAYOUT#'"); @@ -791,8 +796,9 @@ void BinningProblem::addToProblem(SourceFile *routine) if (!gapFound) { - ERROR(std::string("start address of fixed address file '") + \ - routine->fileName + "' already occupied or out of range"); + ERROR(std::string("start address of fixed address file '") + + routine->fileName + "' (" + std::to_string(routine->startAddr) + + ") already occupied or out of range"); } } } From 48b56968ed3578ee5325a81a89c3a09514d51be4 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 7 Feb 2020 19:25:09 +0100 Subject: [PATCH 41/66] some more bits for exotic hardware support --- Makefile | 7 +- c64/aliases/,aliases_hardware_cx16.s | 73 +++++++++++++++++++ c64/aliases/,aliases_rom_cart.s | 5 ++ c64/basic/init/e394.basic_cold_start.s | 2 +- c64/kernal/assets/cartridge_signature.s | 1 + c64/kernal/init/cartridge_check.s | 1 + c64/kernal/init/fce2.hw_entry_reset.s | 4 +- c64/kernal/init/fd50.ramtas.s | 17 +++++ .../interrupts/fe47.default_nmi_handler.s | 5 ++ c64/kernal/jumptable/fff3.jiobase.s | 15 ++++ 10 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 c64/aliases/,aliases_hardware_cx16.s diff --git a/Makefile b/Makefile index 49f6bd6e..71466c12 100644 --- a/Makefile +++ b/Makefile @@ -398,11 +398,14 @@ test_generic_x128: build/kernal_generic.rom build/basic_generic.rom build/symbol test_testing: build/kernal_testing.rom build/basic_testing.rom build/symbols_testing.vs x64 -kernal build/kernal_testing.rom -basic build/basic_testing.rom -moncommands build/symbols_testing.vs -1 $(TESTTAPE) -8 $(TESTDISK) +test_ultimate64: build/kernal_ultimate64.rom build/basic_ultimate64.rom build/symbols_ultimate64.vs + x64 -kernal build/kernal_ultimate64.rom -basic build/basic_ultimate64.rom -moncommands build/symbols_ultimate64.vs -1 $(TESTTAPE) -8 $(TESTDISK) + test_mega65: $(TARGET_M65_x) ../xemu/build/bin/xmega65.native -dmarev 2 -forcerom -loadrom $(TARGET_M65_x) -test_ultimate64: build/kernal_ultimate64.rom build/basic_ultimate64.rom build/symbols_ultimate64.vs - x64 -kernal build/kernal_ultimate64.rom -basic build/basic_ultimate64.rom -moncommands build/symbols_ultimate64.vs -1 $(TESTTAPE) -8 $(TESTDISK) +test_cx16: $(TARGET_X16_x) + ../x16-emulator/x16emu -rom $(TARGET_X16_x) test_hybrid: build/kernal_hybrid.rom build/symbols_hybrid.vs @echo diff --git a/c64/aliases/,aliases_hardware_cx16.s b/c64/aliases/,aliases_hardware_cx16.s new file mode 100644 index 00000000..79bfbb4a --- /dev/null +++ b/c64/aliases/,aliases_hardware_cx16.s @@ -0,0 +1,73 @@ + +// +// Names of hardware registers +// + + +#if CONFIG_PLATFORM_COMMANDER_X16 + + // VERA registers + + .label __VERA_BASE = $9F20 // base address of the chip + + .label VERA_ADDR_LO = $9F20 + .label VERA_ADDR_MID = $9F21 + .label VERA_ADDR_HI = $9F22 + + .label VERA_DATA0 = $9F23 + .label VERA_DATA1 = $9F24 + + .label VERA_CTRL = $9F25 + + .label VERA_IEN = $9F26 + .label VERA_ISR = $9F27 + + // VIA #1 registers + + .label __VIA1_BASE = $9F60 // base address of the chip + + .label VIA1_PRB = $9F60 + .label VIA1_PRA = $9F61 + .label VIA1_DDRB = $9F62 + .label VIA1_DDRA = $9F63 + + .label VIA1_T1C_L = $9F64 + .label VIA1_T1C_H = $9F65 + .label VIA1_T1L_L = $9F66 + .label VIA1_T1L_H = $9F67 + .label VIA1_T2C_L = $9F68 + .label VIA1_T2C_H = $9F69 + + .label VIA1_SR = $9F6A + .label VIA1_ACR = $9F6B + .label VIA1_PCR = $9F6C + .label VIA1_IFR = $9F6D + .label VIA1_IER = $9F6E + + .label VIA1_PRA_NH = $9F6F + + // VIA #2 registers + + .label __VIA2_BASE = $9F70 // base address of the chip + + .label VIA2_PRB = $9F70 + .label VIA2_PRA = $9F71 + .label VIA2_DDRB = $9F72 + .label VIA2_DDRA = $9F73 + + .label VIA2_T1C_L = $9F74 + .label VIA2_T1C_H = $9F75 + .label VIA2_T1L_L = $9F76 + .label VIA2_T1L_H = $9F77 + .label VIA2_T2C_L = $9F78 + .label VIA2_T2C_H = $9F79 + + .label VIA2_SR = $9F7A + .label VIA2_ACR = $9F7B + .label VIA2_PCR = $9F7C + .label VIA2_IFR = $9F7D + .label VIA2_IER = $9F7E + + .label VIA2_PRA_NH = $9F7F + +#endif diff --git a/c64/aliases/,aliases_rom_cart.s b/c64/aliases/,aliases_rom_cart.s index 50decc3f..620960a7 100644 --- a/c64/aliases/,aliases_rom_cart.s +++ b/c64/aliases/,aliases_rom_cart.s @@ -1,5 +1,10 @@ +#if CONFIG_PLATFORM_COMMODORE_64 + // Cartridge ROM locations + .label ICART_COLD_START = $8000 // $8000-$8001, cartridge cold start vector .label ICART_WARM_START = $8002 // $8002-$8003, cartridge warm start vector (RESTORE key) .label CART_SIG = $8004 // $8004-$8008, signature for cartridge detection + +#endif diff --git a/c64/basic/init/e394.basic_cold_start.s b/c64/basic/init/e394.basic_cold_start.s index 670cdda6..a7ba4138 100644 --- a/c64/basic/init/e394.basic_cold_start.s +++ b/c64/basic/init/e394.basic_cold_start.s @@ -8,7 +8,7 @@ basic_cold_start: -#if !ROM_LAYOUT_M65 // can be safely skipped in Mega65 ROM layout +#if ROM_LAYOUT_STD // skip on non-sgtandard ROM layouts - they produce single image nevertheless // Before doing anything, check if we have a compatible BASIC/KERNAL pair diff --git a/c64/kernal/assets/cartridge_signature.s b/c64/kernal/assets/cartridge_signature.s index a0fdcc4b..92a3b776 100644 --- a/c64/kernal/assets/cartridge_signature.s +++ b/c64/kernal/assets/cartridge_signature.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/init/cartridge_check.s b/c64/kernal/init/cartridge_check.s index b47c61e7..3686a7f8 100644 --- a/c64/kernal/init/cartridge_check.s +++ b/c64/kernal/init/cartridge_check.s @@ -1,4 +1,5 @@ // #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE diff --git a/c64/kernal/init/fce2.hw_entry_reset.s b/c64/kernal/init/fce2.hw_entry_reset.s index 474668f2..0d36a2d6 100644 --- a/c64/kernal/init/fce2.hw_entry_reset.s +++ b/c64/kernal/init/fce2.hw_entry_reset.s @@ -19,6 +19,8 @@ hw_entry_reset: ldx #$FF txs +#if CONFIG_PLATFORM_COMMODORE_64 + // The following routine is based on reading the public KERNAL jumptable routine // list, and making unimaginative assumptions about what should be done on reset. // Also, https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image was used @@ -30,10 +32,10 @@ hw_entry_reset: jmp (ICART_COLD_START) !: -#if CONFIG_PLATFORM_COMMODORE_64 // Disable the screen (and set 40 columns) to prevent visual glitches later ldx #$28 stx VIC_SCROLX + #endif // Initialising IO is obviously required. Also indicated by c64 prg p269. diff --git a/c64/kernal/init/fd50.ramtas.s b/c64/kernal/init/fd50.ramtas.s index 412797bc..70a4abc2 100644 --- a/c64/kernal/init/fd50.ramtas.s +++ b/c64/kernal/init/fd50.ramtas.s @@ -49,6 +49,8 @@ RAMTAS: ldx #>$033C stx TAPE1+1 +#if CONFIG_PLATFORM_COMMODORE_64 + // Set screen address pointer ("Compute's Mapping the 64" p238) // This is obvious boiler plate containing no creative input, but to avoid // unnecessarily similarity to the C64 KERNAL, we use X instead of A to do this, @@ -95,4 +97,19 @@ ramtas_32k: ldy #$80 bne !- // branch always +#elif CONFIG_PLATFORM_COMMANDER_X16 + + ldx #>$0800 + stx MEMSTR+1 + + ldy #$9F + sty MEMSIZK+1 + +#else + + .error "Please fill-in RAMTAS" + +#endif // platform + + #endif // ROM layout diff --git a/c64/kernal/interrupts/fe47.default_nmi_handler.s b/c64/kernal/interrupts/fe47.default_nmi_handler.s index 96a2bccb..5e86373f 100644 --- a/c64/kernal/interrupts/fe47.default_nmi_handler.s +++ b/c64/kernal/interrupts/fe47.default_nmi_handler.s @@ -17,10 +17,15 @@ default_nmi_handler: // XXX confirm NMIs from CIA, or no other NMI will arrive! +#if CONFIG_PLATFORM_COMMODORE_64 + jsr cartridge_check bne !+ jmp (ICART_WARM_START) !: + +#endif + // According to C64 Wiki, if STOP key is pressed, the routine assumes warm start request // XXX is it right? how to check that IRQ was caused by RESTORE? diff --git a/c64/kernal/jumptable/fff3.jiobase.s b/c64/kernal/jumptable/fff3.jiobase.s index 8f0b756b..0af3c7a1 100644 --- a/c64/kernal/jumptable/fff3.jiobase.s +++ b/c64/kernal/jumptable/fff3.jiobase.s @@ -16,6 +16,21 @@ // As there is nothing between here and $FFFA, we can just hard code this in place. // iobase: - commented out to prevent label naming conflict + +#if CONFIG_PLATFORM_COMMODORE_64 + ldy #$DC ldx #$00 + +#elif CONFIG_PLATFORM_COMMANDER_X16 + + ldy #$9F + ldx #$60 + +#else + + .error "Please fill-in IOBASE" + +#endif + rts From dd23d570d3c4f8eb0bb35e1e2347745039d0f38a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 7 Feb 2020 19:51:10 +0100 Subject: [PATCH 42/66] makefile dependencies fix --- Makefile | 12 ++++++------ c64/,,config_cx16.s | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 71466c12..6bae0f85 100644 --- a/Makefile +++ b/Makefile @@ -61,12 +61,12 @@ DIR_X16 = build/target_cx16 # List of config files -CFG_CUSTOM = c64/,,config_custom.s -CFG_GEN = c64/,,config_generic.s -CFG_TESTING = c64/,,config_testing.s -CFG_M65 = c64/,,config_mega65.s -CFG_U64 = c64/,,config_ultimate64.s -CFG_X16 = c64/,,config_cx16.s +CFG_CUS = c64/,,config_custom.s +CFG_GEN = c64/,,config_generic.s +CFG_TST = c64/,,config_testing.s +CFG_M65 = c64/,,config_mega65.s +CFG_U64 = c64/,,config_ultimate64.s +CFG_X16 = c64/,,config_cx16.s # Dependencies - helper variables diff --git a/c64/,,config_cx16.s b/c64/,,config_cx16.s index 9b94dcd9..828f0e73 100644 --- a/c64/,,config_cx16.s +++ b/c64/,,config_cx16.s @@ -24,7 +24,7 @@ // #define CONFIG_BRAND_MEGA_65 // #define CONFIG_BRAND_ULTIMATE_64 -.const CONFIG_CUSTOM_BRAND = @"COMMANDER X16" +.const CONFIG_CUSTOM_BRAND = @"FOR COMMANDER X16" // Processor instruction set From 1997ed9f9084662c43cd6375c853241ffa86552a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 7 Feb 2020 21:38:02 +0100 Subject: [PATCH 43/66] KickAssembler updated --- assembler/KickAss.jar | Bin 624712 -> 625225 bytes assembler/KickAssembler.pdf | Bin 783928 -> 785388 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/assembler/KickAss.jar b/assembler/KickAss.jar index 82560fa2906d79fafc526267f3defcfd3ec2d56b..3adf7b5e541ab80f17780106e7ed0b96d311401b 100644 GIT binary patch delta 62895 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%0DEl_OM^G#sZ>|@Jfw3Qt#gT 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

? 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 Rxyr!aZrXy=(!g`0{s&L+?l39owif8YE3 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¥lFyceeoLm=o~t= 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

Vw63LdYMl3c9NM$Zo^F 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

$US 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 P;6R|Hd-oAuZj%229{upi delta 71398 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

    p#pLC@Q0p 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 Date: Mon, 10 Feb 2020 17:35:04 +0100 Subject: [PATCH 44/66] some code for floating point addition --- c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s index f8aaf267..bf18b367 100644 --- a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s @@ -21,4 +21,37 @@ // XXX provide implementation add_FAC2_FAC1: + + // Check if FAC2 is 0; if so, leave FAC1 without changes + + lda FAC2_exponent + beq add_FAC2_FAC1_done + + // If FAC1 is 0, just copy FAC2 to FAC1 + + lda FAC1_exponent + beq_16 mov_FAC2_FAC1 + + // Make sure the exponents are aligned + + jsr add_align_exponents + + // Check whether signs are the same + + lda FAC1_sign + eor FAC2_sign + + bmi add_FAC2_FAC1_sub // branch if signs are opposite + + + + + +add_FAC2_FAC1_sub: + STUB_IMPLEMENTATION() + + +add_FAC2_FAC1_done: + + rts \ No newline at end of file From a515ae82ca52286798c2af657a000023dcb54211 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 10 Feb 2020 17:48:24 +0100 Subject: [PATCH 45/66] makefile fix --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6bae0f85..da8927c1 100644 --- a/Makefile +++ b/Makefile @@ -88,10 +88,10 @@ TOOLS_LIST = $(pathsubst tools/%,build/tools/%,$(basename $(SRC_TOOLS))) # List of targets -TARGET_CUS_B = build/kernal_custom.rom -TARGET_GEN_B = build/kernal_generic.rom -TARGET_TST_B = build/kernal_testing.rom -TARGET_U64_B = build/kernal_ultimate64.rom +TARGET_CUS_B = build/basic_custom.rom +TARGET_GEN_B = build/basic_generic.rom +TARGET_TST_B = build/basic_testing.rom +TARGET_U64_B = build/basic_ultimate64.rom TARGET_CUS_K = build/kernal_custom.rom TARGET_GEN_K = build/kernal_generic.rom @@ -124,7 +124,7 @@ SEG_LIST_X16 = $(DIR_X16)/basic.seg_0 \ $(DIR_X16)/kernal.seg_0 \ $(DIR_X16)/kernal.seg_1 -REL_TARGET_LIST = $(TARGET_LIST_CUS) $(TARGET_LIST_GEN) $(TARGET_LIST_TST) $(TARGET_M65_x) $(TARGET_LIST_U64) +REL_TARGET_LIST = $(TARGET_LIST_GEN) $(TARGET_LIST_TST) $(TARGET_M65_x) $(TARGET_LIST_U64) # Misc strings @@ -146,7 +146,7 @@ clean: updatebin: $(MAKE) -j64 --output-sync=target $(TARGET_LIST) $(TOOL_RELEASE) - $(TOOL_RELEASE) -i ./build -o ./bin $(pathsubst build/%,./%, $(REL_TARGET_LIST)) + $(TOOL_RELEASE) -i ./build -o ./bin $(patsubst build/%,%,$(REL_TARGET_LIST)) cp build/chargen.rom bin/chargen.rom # Rules - tools From c51f10ff46e482f16bc234da372dc6b2af9551e7 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 10 Feb 2020 17:48:50 +0100 Subject: [PATCH 46/66] fix for INS (SHIFT+DEL) in quote mode --- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes .../screen/chrout_screen_jumptable_codes.s | 8 ++++---- 8 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 92f77191493d587177a780d190d160c826549581..21915674b22e052c9d7dfed6a98da1c83dee5908 100644 GIT binary patch literal 8192 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 delta 2189 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 MQRh!WzY_@m0p8H1WB>pF delta 2315 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 delta 2171 zcmcgtZ*Uvc5x>*fKKT!pZ0uOJYvFvGSeY^YH-|mg{jr94RTbf?Fum9e=?!N2WTUP#uPnNHE+DFtCZ&`7+ z-523myvZK*kcF&%C%KUKMu@OTE@cBPxbj{jpQ{M0FNmQX?tz?h2nq(42y6E?ZS*C=@xLM}_W_yL zdlZ)<2ns7de=D36B){`ID>}a!PD%obIvsOL`YmHslFr7eB}^=?CP*vL=_M=*@923) zR0nw{!abyX7PEwL@MpUvdMHTFg-B_To(VAt%U0%3xFcSxwwJUwN;=xc)vfwvb=y%S z2g{Q^i{44Eam=)-7t`jPK8%$}o9F0)=8_+@&4sl`<*oIYzy%DJZUu`6ri?_e;OkMe z*Vb>)4i`6;9!i}SY^(IWu*QlTeG6GG=UxlRF~Mf^nG(Hk%2Rg%BKCW!CU7OVE9sBlTnu8cY2}$Yn5#8c}(VHt|{3*hg0(nG_@3w?oA0Ap+ z7D?7cJjrzt4_YZ$<#M!ZLpzDKG3y{C$WA*USfw56S9!0xljuv_UAzmCSq>N261ODn zu)W?ltowpLgh$~q_z^q~Pr#4iC$JsvfG1%PhTt%~2?v8eg<&`s^}z`I44#6Y!_%O` zsnApW2)vm31^8hU4)de%4Ez$tU>uIY1Uw7B0u7#nogZ#nWhU- zvM+dKhV+Nxl@{-6(c%`yYt$J$>%6sHQ`k0T+&fQioeI?iYt5oyXQ%_`^mG@wont>@6?Fj{g8U(pY zL6&sTp(%1KMv{3lm&XLum}Rw)B^Rd(tzteL6R~5=2dOXi-+>x-XK`Gj8<{$T+VrB1 zVSRo^z(MBMPGiE{K(1zhOy^Ap`ODhgNx_z;SEdy7fwlp`-(89=hn>G_UPCv!5Sn2M znaNvm&E?~J0|K5FA3*c?9_w#6SN$um^+nMlzT^%VS37jT524;1EsbwHI!h zw_RP-4pp{j{UtRCvMPOk4N6_~)TGg6I=BO0K-gFax`VoBaU|a}i_PpPG+@+}Q9gvd zqwQ*}vuA>+K{7#YUt>#6Bez=WMiMOp_T&3A&Kv3vw7)mG52j{~+a@+4$}*xX(bO!z zXf~g9im@tDmC2bHw;N7`xq*?Zvl9((R*B{-_;jjTL%oFQ+GUpALl)AJSP`=Rp8qL8~elN`U??#Pu}tMN%r zqSt5HNI^Embi2huF^zgf8G1+R1P)PMP`>#s>7M@Yc5UhI-n^x!Yxmc>HVeWRys<52 zV97ptp5Bin!?Cw$LlRxdCyAY=V3wjy=cI-`wQpuY9*lv#z;lhWqo$DH{0DQs9b^Ci diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index e5202c4e3621d53d31fb1df895217658f89a6cf9..8966cd22fa2dfc88ee8d93e1b0dae0c21c3d7bf8 100644 GIT binary patch delta 4047 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 Db&|RI delta 4802 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 diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index eb9aa28f3aa6cf4c2d03ea8c7f5b2c158c3344c2..36d43691c572d95e5b38162431ba98d58e0e2fe5 100644 GIT binary patch delta 3075 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 A9smFU delta 4642 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 delta 6532 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 - 1) .byte >(chrout_screen_CRSR_DOWN - 1) .byte >(chrout_screen_CRSR_UP - 1) + .byte >(chrout_screen_INS - 1) #if CONFIG_EDIT_STOPQUOTE .byte >(chrout_screen_STOP - 1) #endif @@ -88,7 +89,6 @@ chrout_screen_jumptable_hi: .byte >(chrout_screen_TAB_BW - 1) .byte >(chrout_screen_TAB_FW - 1) #endif - .byte >(chrout_screen_INS - 1) .byte >(chrout_screen_DEL - 1) .byte >(chrout_screen_RETURN - 1) @@ -110,6 +110,7 @@ chrout_screen_jumptable: .word chrout_screen_CRSR_LEFT .word chrout_screen_CRSR_DOWN .word chrout_screen_CRSR_UP + .word chrout_screen_INS #if CONFIG_EDIT_STOPQUOTE .word chrout_screen_STOP #endif @@ -117,7 +118,6 @@ chrout_screen_jumptable: .word chrout_screen_TAB_BW .word chrout_screen_TAB_FW #endif - .word chrout_screen_INS .word chrout_screen_DEL .word chrout_screen_RETURN From dea993e4b72b1ca57cb6b05f01eefcf5e75a5df8 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 10 Feb 2020 18:14:44 +0100 Subject: [PATCH 47/66] partial fix for quote-mode DEL --- c64/kernal/screen/chrout_screen_del.s | 1 + 1 file changed, 1 insertion(+) diff --git a/c64/kernal/screen/chrout_screen_del.s b/c64/kernal/screen/chrout_screen_del.s index 96b8c46b..807e4b79 100644 --- a/c64/kernal/screen/chrout_screen_del.s +++ b/c64/kernal/screen/chrout_screen_del.s @@ -13,6 +13,7 @@ chrout_screen_DEL: // In insert mode it embeds control character ldx INSRT beq !+ + lda #KEY_DEL jmp chrout_screen_quote !: ldy PNTR From 37ae435b2dfddbe5defb4ea3f089ccbf391683a8 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 11 Feb 2020 22:48:33 +0100 Subject: [PATCH 48/66] prepared QTSW flag for proper screen code -> PETSCII conversion --- c64/kernal/keyboard/chrin_keyboard.s | 20 ++++++++++++------ c64/kernal/screen/chrout_screen.s | 7 +------ c64/kernal/screen/screen_check_toggle_quote.s | 21 +++++++++++++++++++ c64/kernal/screen/screen_code_to_petscii.s | 3 +++ 4 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 c64/kernal/screen/screen_check_toggle_quote.s diff --git a/c64/kernal/keyboard/chrin_keyboard.s b/c64/kernal/keyboard/chrin_keyboard.s index 6645a9b8..7e914c6d 100644 --- a/c64/kernal/keyboard/chrin_keyboard.s +++ b/c64/kernal/keyboard/chrin_keyboard.s @@ -31,9 +31,10 @@ chrin_repeat: cmp INDX bne not_end_of_input - // Return carriage return and clear pending input flag + // Return carriage return and clear pending input and quote flags lda #$00 sta CRSW + sta QTSW // FALLTROUGH @@ -54,8 +55,10 @@ not_end_of_input: // Return next byte of waiting tay + chrin_keyboard_return_byte: lda (LXSP),y + jsr screen_check_toggle_quote tax ply_trash_a txa @@ -112,7 +115,7 @@ chrin_enter_calc_length: // Calculate length jsr screen_get_logical_line_end_ptr iny - + chrin_enter_loop: // Retrieve bytes @@ -123,12 +126,17 @@ chrin_enter_loop: beq chrin_enter_loop iny sty INDX - lda #$01 - sta CRSW + + // Set mark informing that we are returning a line + ldy #$01 + sty CRSW + + // Clear quote mode mark + dey // set .Y to 0 + sty QTSW // Return first char of line - ldy #$00 - beq chrin_keyboard_return_byte // branch always + beq chrin_keyboard_return_byte // branch always not_enter: diff --git a/c64/kernal/screen/chrout_screen.s b/c64/kernal/screen/chrout_screen.s index 14c583b5..5118c854 100644 --- a/c64/kernal/screen/chrout_screen.s +++ b/c64/kernal/screen/chrout_screen.s @@ -86,13 +86,8 @@ chrout_screen_literal: // Toggle quote flag if required txa - cmp #$22 - bne !+ + jsr screen_check_toggle_quote - lda QTSW - eor #$80 - sta QTSW -!: // Set colour of the newly printed character lda COLOR diff --git a/c64/kernal/screen/screen_check_toggle_quote.s b/c64/kernal/screen/screen_check_toggle_quote.s new file mode 100644 index 00000000..255f1d19 --- /dev/null +++ b/c64/kernal/screen/screen_check_toggle_quote.s @@ -0,0 +1,21 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE +// #LAYOUT# * KERNAL_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Helper routine - check character in .A, toggles quote flag if needed +// + +screen_check_toggle_quote: + + cmp #$22 + bne !+ + + lda QTSW + eor #$80 + sta QTSW + + lda #$22 // restore previous .A valuee +!: + rts diff --git a/c64/kernal/screen/screen_code_to_petscii.s b/c64/kernal/screen/screen_code_to_petscii.s index 898f2883..4b0e00ad 100644 --- a/c64/kernal/screen/screen_code_to_petscii.s +++ b/c64/kernal/screen/screen_code_to_petscii.s @@ -4,6 +4,9 @@ // #LAYOUT# * * #IGNORE +// XXX - conversion should depend on QTSW too + + screen_code_to_petscii: cmp #$1B bcc s2p_adc_40 From af1f5b079d885bb5cbf7898ab7e18c47056c664a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 12 Feb 2020 20:37:10 +0100 Subject: [PATCH 49/66] fixed screen code to PETSCII conversion --- .../screen/chrout_screen_jumptable_codes.s | 6 +- c64/kernal/screen/screen_code_to_petscii.s | 79 +++++++++++++------ 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/c64/kernal/screen/chrout_screen_jumptable_codes.s b/c64/kernal/screen/chrout_screen_jumptable_codes.s index 303c48c4..66e56e74 100644 --- a/c64/kernal/screen/chrout_screen_jumptable_codes.s +++ b/c64/kernal/screen/chrout_screen_jumptable_codes.s @@ -94,6 +94,8 @@ chrout_screen_jumptable_hi: #else +__before_chrout_screen_jumptable: + .if (mod(*, $2) == 1) { brk } // align code so that vector never crosses page boundary chrout_screen_jumptable: @@ -121,6 +123,8 @@ chrout_screen_jumptable: .word chrout_screen_DEL .word chrout_screen_RETURN -.if (mod(*, $2) == 0) { brk } // make sure routine size is always the same, needed by build system + // Make sure routine size is always the same - build system limitation + +.if (__before_chrout_screen_jumptable == chrout_screen_jumptable) { brk } #endif diff --git a/c64/kernal/screen/screen_code_to_petscii.s b/c64/kernal/screen/screen_code_to_petscii.s index 4b0e00ad..1a66bff6 100644 --- a/c64/kernal/screen/screen_code_to_petscii.s +++ b/c64/kernal/screen/screen_code_to_petscii.s @@ -3,42 +3,73 @@ // #LAYOUT# * KERNAL_0 #TAKE // #LAYOUT# * * #IGNORE +// +// Screen code to PETSCII conversion - see: +// +// - https://www.lemon64.com/forum/viewtopic.php?t=66362 +// - https://sta.c64.org/cbm64scrtopetext.html +// -// XXX - conversion should depend on QTSW too + +// XXX - part below might depend on QTSW too screen_code_to_petscii: - cmp #$1B - bcc s2p_adc_40 - -s2p_not_alpha: + + cmp #$20 + bcc s2p_adc_40 // $00-$1F -> $40-$5F + cmp #$40 - bcc s2p_end + bcc s2p_end // $20-$3F -> $20-$3F - // FALLTROUGH - -s2p_not_punctuation: - cmp #$5B - bcs s2p_not_shifted - - // carry already clear here - adc #$80 - - rts - -s2p_not_shifted: + cmp #$60 + bcc s2p_adc_80 // $40-$5F -> $C0-$DF cmp #$80 - bcs s2p_end // not vendor + bcc s2p_adc_40 // $60-$7F -> $A0-$BF - // $60-$7F -> $A0-$BF + // Here we have to check for quote mode + + bit QTSW + bmi screen_code_to_petscii_quote + + // Not quote mode - continue + + cmp #$A0 + bcc s2p_adc_C0 // $80-$9F -> $40-$5F + + cmp #$C0 + bcc s2p_adc_80 // $A0-$BF -> $20-$3F + + cmp #$E0 + bcc s2p_end // $C0-$DF -> $C0-$DF + + clc + bcc s2p_adc_C0 // $E0-$FF -> $A0-$BF s2p_adc_40: - clc - adc #$40 - - // FALLTROUGH + adc #$40 // Carry already clear s2p_end: + + rts + +s2p_adc_80: + + adc #$80 // Carry already clear + rts + +screen_code_to_petscii_quote: + + cmp #$C0 + bcc s2p_adc_80 // $80-$BF -> $00-$3F + + clc + + // FALLTROUGH $C0-$FF -> $80-$BF + +s2p_adc_C0: + + adc #$C0 // Carry already clear rts From 5fd45f1ece7c60e60212225f069d699ed96d6102 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 12 Feb 2020 20:43:48 +0100 Subject: [PATCH 50/66] fixed 2 typos in syymbol names, updated binaries --- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes c64/aliases/,aliases_ram_lowmem.s | 4 ++-- c64/kernal/keyboard/chrin_keyboard.s | 20 +++++++++--------- c64/kernal/screen/chrout_screen_ins.s | 2 +- c64/kernal/screen/chrout_screen_return.s | 2 +- c64/kernal/screen/e544.clear_screen.s | 4 ++-- c64/kernal/screen/e8ea.screen_scroll_up.s | 10 ++++----- .../screen/screen_calculate_pntr_lnmx.s | 6 +++--- .../screen/screen_get_logical_line_end_ptr.s | 4 ++-- c64/kernal/screen/screen_grow_logical_line.s | 12 +++++------ 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 21915674b22e052c9d7dfed6a98da1c83dee5908..a6b3a27e12b5bab2a0119ccabf451ae57bca33e5 100644 GIT binary patch delta 164 zcmZp0XmHq&!@_j_>E=8ZUq&E3c`xf~-iUWgHz-8BQ#k+Br*`Q?LCMK|Y!-~iCm&}E z0I8H@zt6;YeDhCEEe?(5g1X2HlOn}s86Jb6!wvNv}D_7*F$ICAS E0QYrA@Bjb+ delta 164 zcmZp0XmHq&!@~6O)#f}FUq&E3c`xf~-p+SRHz;(zQ~3DGr*`Q?LCMK|Y!-}fCLd=D z0I8H@zt6<@X7f)@Ee?(5g1X2HlOn}s86Jb6!w)0PY?!Hc#C}=%d zTZV7)2Pw{p3QC*zNQy8^eSEdjUg6UJj8zIpS1P=DwMY>}e|!Z*n_tP4FfkfTj+b8u E0104xT|Kw!jVAPu=q|2x`Sx?9cNM;I|0?nE)^qifw7?o-!I*up#EM#Z}WcXG)6|v$!fBpK*cq(w}6Vn<=7b+jV8y-XGmhRUP14Tg5Kl@ G@(KV}ib9(J delta 178 zcmZp0XmHq&!@?N3IhVzc5lHP}m0{F~e6!MC;nM$%RSHK}DuldQqzI&!TAlp=foG9C zn7PbSVeLAF$W81&m>5Gg|Kw!jV2qq3q{|pNSx?9cNM;I|0?nE)^qieF^P>;v+s)ll z+Kikw@0V^+uz9Z#xp}{I8Y5%KWHs4PpyC?YTR_F(a_o$Z29x9EGbFKDuMqi0A#(Bq Gc?AFww?xbU diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index ff716437f734af5a37f4d8015b8ffa81b68310c8..bd9dfcf4f2b98e27c7dbb15792ab3d278e1d385c 100644 GIT binary patch delta 152 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 diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index 36d43691c572d95e5b38162431ba98d58e0e2fe5..7bd2be849d7edf40f59963f6f9ec396cea0a657c 100644 GIT binary patch delta 2974 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 RukkwWA)BCl{oR-9e*y0esl)&P delta 2954 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 b*rMS!mRwctgr1&gr=rE}EcyShjxG2fxW~5s diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 828aef45..fa426b09 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -145,7 +145,7 @@ .label NDX = $C6 // number of chars in keyboard buffer .label RVS = $C7 // flag, whether to print reversed characters .label INDX = $C8 // end of logical line (column, 0-79) - .label LXSP = $C9 // $C9-$CA start of input, X/Y position + .label LSXP = $C9 // $C9-$CA start of input, X/Y position (typo in Mapping the C64, fixed in Mapping the C128) .label SFDX = $CB // -- NOT IMPLEMENTED -- .label BLNSW = $CC // cursor blink disable flag .label BLNCT = $CD // cursor blink countdown @@ -159,7 +159,7 @@ .label TBLX = $D6 // current screen Y position (row), 0-24 .label SCHAR = $D7 // ASCII value of the last printed character .label INSRT = $D8 // insert mode flag/counter - .label LDTBL = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details + .label LDTB1 = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details .label USER = $F3 // $F3-$F4 pointer to current color RAM location .label KEYTAB = $F5 // $F5-$F6 pointer to keyboard lookup table .label RIBUF = $F7 // $F7-$F8 -- WIP -- RS-232 receive buffer pointer diff --git a/c64/kernal/keyboard/chrin_keyboard.s b/c64/kernal/keyboard/chrin_keyboard.s index 7e914c6d..a7ab5e83 100644 --- a/c64/kernal/keyboard/chrin_keyboard.s +++ b/c64/kernal/keyboard/chrin_keyboard.s @@ -25,7 +25,7 @@ chrin_repeat: lda CRSW beq read_from_keyboard - // Yes, we have input waiting at (LXSP)+CRSW + // Yes, we have input waiting at (LSXP)+CRSW // When CRSW = INDX, then we return a carriage return // and clear the flag cmp INDX @@ -57,7 +57,7 @@ not_end_of_input: tay chrin_keyboard_return_byte: - lda (LXSP),y + lda (LSXP),y jsr screen_check_toggle_quote tax ply_trash_a @@ -92,20 +92,20 @@ chrin_enter: // Set pointer to line of input lda PNT+0 - sta LXSP+0 + sta LSXP+0 lda PNT+1 - sta LXSP+1 + sta LSXP+1 - // If the current line is a continuation of the previous one, decrease LXSP by 40 + // If the current line is a continuation of the previous one, decrease LSXP by 40 ldy TBLX - lda LDTBL, y + lda LDTB1, y bmi chrin_enter_calc_length // branch if not continuation - lda LXSP+0 + lda LSXP+0 sec sbc #40 - sta LXSP+0 + sta LSXP+0 bcs !+ - dec LXSP+1 + dec LSXP+1 !: ldy #80 bne chrin_enter_loop // branch always @@ -121,7 +121,7 @@ chrin_enter_loop: // Retrieve bytes dey bmi empty_line - lda (LXSP),y + lda (LSXP),y cmp #$20 beq chrin_enter_loop iny diff --git a/c64/kernal/screen/chrout_screen_ins.s b/c64/kernal/screen/chrout_screen_ins.s index 61ac4211..0e3eed38 100644 --- a/c64/kernal/screen/chrout_screen_ins.s +++ b/c64/kernal/screen/chrout_screen_ins.s @@ -26,7 +26,7 @@ chrout_screen_ins_possible: // Special handling for cursor in second line ldx TBLX - lda LDTBL+0, x + lda LDTB1+0, x bpl chrout_screen_ins_second_line // Perform character copy diff --git a/c64/kernal/screen/chrout_screen_return.s b/c64/kernal/screen/chrout_screen_return.s index 5f42ae14..93a28a19 100644 --- a/c64/kernal/screen/chrout_screen_return.s +++ b/c64/kernal/screen/chrout_screen_return.s @@ -24,7 +24,7 @@ chrout_screen_RETURN: cpy #24 beq !+ // last line on screen - no need for a double line skip - lda LDTBL+1, y + lda LDTB1+1, y bmi !+ // current line is not continued inc TBLX diff --git a/c64/kernal/screen/e544.clear_screen.s b/c64/kernal/screen/e544.clear_screen.s index 7c241c09..8c3abe1d 100644 --- a/c64/kernal/screen/e544.clear_screen.s +++ b/c64/kernal/screen/e544.clear_screen.s @@ -17,9 +17,9 @@ clear_screen: // continuation of the previous one lda #$80 - ldy #24 + ldy #24 !: - sta LDTBL,y + sta LDTB1,y dey bpl !- diff --git a/c64/kernal/screen/e8ea.screen_scroll_up.s b/c64/kernal/screen/e8ea.screen_scroll_up.s index 2b11f352..7d4712d4 100644 --- a/c64/kernal/screen/e8ea.screen_scroll_up.s +++ b/c64/kernal/screen/e8ea.screen_scroll_up.s @@ -47,18 +47,18 @@ screen_scroll_up: screen_scroll_up_delay_done: // entry point for cursor move control codes - // Scroll the LDTBL (line link table) + // Scroll the LDTB1 (line link table) ldy #$00 !: - lda LDTBL+1, y - sta LDTBL+0, y + lda LDTB1+1, y + sta LDTB1+0, y iny cpy #24 bne !- lda #$80 - sta LDTBL+24 + sta LDTB1+24 // Preserve SAL and EAL, prepare initial SAL/EAL/PNT/USER values @@ -126,7 +126,7 @@ screen_scroll_up_loop_done: // If the first line is linked, scroll once more - bit LDTBL+0 + bit LDTB1+0 bpl screen_scroll_up // Recalculate PNT and USER diff --git a/c64/kernal/screen/screen_calculate_pntr_lnmx.s b/c64/kernal/screen/screen_calculate_pntr_lnmx.s index b024c448..75c31643 100644 --- a/c64/kernal/screen/screen_calculate_pntr_lnmx.s +++ b/c64/kernal/screen/screen_calculate_pntr_lnmx.s @@ -12,7 +12,7 @@ screen_calculate_PNTR_LNMX: ldy TBLX - lda LDTBL, y + lda LDTB1, y php jsr screen_get_clipped_PNTR plp @@ -38,14 +38,14 @@ screen_calculate_PNTR_0_39: screen_calculate_LNMX: ldy TBLX - lda LDTBL, y + lda LDTB1, y bpl screen_calculate_lnmx_79 // this line is a continuation cpy #24 beq screen_calculate_lnmx_39 // this is the last line, which is not a continuation iny - lda LDTBL, y + lda LDTB1, y bpl screen_calculate_lnmx_79 // line is continued // FALLTROUGH diff --git a/c64/kernal/screen/screen_get_logical_line_end_ptr.s b/c64/kernal/screen/screen_get_logical_line_end_ptr.s index b2bbc293..d52dbc75 100644 --- a/c64/kernal/screen/screen_get_logical_line_end_ptr.s +++ b/c64/kernal/screen/screen_get_logical_line_end_ptr.s @@ -10,10 +10,10 @@ screen_get_logical_line_end_ptr: cpy #24 bcs screen_get_logical_line_end_39 // last line of the screen - lda LDTBL+0, y + lda LDTB1+0, y bpl screen_get_logical_line_end_39 // current line continues previous one - lda LDTBL+1, y + lda LDTB1+1, y bmi screen_get_logical_line_end_39 // current line is not continued // FALLTROUGH diff --git a/c64/kernal/screen/screen_grow_logical_line.s b/c64/kernal/screen/screen_grow_logical_line.s index 96ecac98..b7e5acc6 100644 --- a/c64/kernal/screen/screen_grow_logical_line.s +++ b/c64/kernal/screen/screen_grow_logical_line.s @@ -26,7 +26,7 @@ screen_grow_logical_line: // Do not grow line if previus one is grown ldy TBLX - lda LDTBL+0, y + lda LDTB1+0, y bpl screen_grow_logical_line_done_scroll // If last line, scroll the screen up @@ -34,22 +34,22 @@ screen_grow_logical_line: beq screen_grow_logical_line_screen_up // Do not grow line if already grown - lda LDTBL+1, y + lda LDTB1+1, y bpl screen_grow_logical_line_done // Preserve SAL and EAL jsr screen_preserve_sal_eal - // Scroll LDTBL down (start from the end) + // Scroll LDTB1 down (start from the end) ldy #23 !: cpy TBLX beq !+ bcc !+ - lda LDTBL+0, y - sta LDTBL+1, y + lda LDTB1+0, y + sta LDTB1+1, y dey bne !- @@ -57,7 +57,7 @@ screen_grow_logical_line: // Mark current line as grown ldy TBLX lda #$00 - sta LDTBL+1, y + sta LDTB1+1, y // Now we have to scroll lines downwards to make space. We start from the end, // and work backwards. We cannot be as simple and efficient here as we are From a665967e17bf7054baaac519a12b7be905a8454b Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 12 Feb 2020 20:45:29 +0100 Subject: [PATCH 51/66] removed obsolete comment left behind --- c64/kernal/screen/screen_code_to_petscii.s | 3 --- 1 file changed, 3 deletions(-) diff --git a/c64/kernal/screen/screen_code_to_petscii.s b/c64/kernal/screen/screen_code_to_petscii.s index 1a66bff6..e19aad58 100644 --- a/c64/kernal/screen/screen_code_to_petscii.s +++ b/c64/kernal/screen/screen_code_to_petscii.s @@ -11,9 +11,6 @@ // -// XXX - part below might depend on QTSW too - - screen_code_to_petscii: cmp #$20 From 0e867480e9bf5f9f1a5c21f9c53d874fd44f42e9 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 12 Feb 2020 21:17:39 +0100 Subject: [PATCH 52/66] floating point add/subtract written, but not tested yet --- STATUS.md | 2 +- c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s | 57 ---------- c64/basic/math/b86a.add_FAC2_FAC1.s | 114 +++++++++++++++++++ c64/basic/{,stubs_math => math}/b86a.interop | 0 4 files changed, 115 insertions(+), 58 deletions(-) delete mode 100644 c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s create mode 100644 c64/basic/math/b86a.add_FAC2_FAC1.s rename c64/basic/{,stubs_math => math}/b86a.interop (100%) diff --git a/STATUS.md b/STATUS.md index ddd0274d..49b5c4c7 100644 --- a/STATUS.md +++ b/STATUS.md @@ -193,7 +193,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B862` | `add_align_exponents` | PARTIAL | not tested yet | | `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B86A` | `add_FAC2_FAC1` | NOT DONE | | +| `$B86A` | `add_FAC2_FAC1` | PARTIAL | not tested yet | | `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | | `$B947` | `inv_FAC1_mantissa` | NOT DONE | | | `$B983` | `MULSHF` | NOT DONE | | diff --git a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s b/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s deleted file mode 100644 index bf18b367..00000000 --- a/c64/basic/,stubs_math/b86a.add_FAC2_FAC1.s +++ /dev/null @@ -1,57 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - add FAC2 to FAC1 -// -// Input: -// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag -// -// Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 112 -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -add_FAC2_FAC1: - - // Check if FAC2 is 0; if so, leave FAC1 without changes - - lda FAC2_exponent - beq add_FAC2_FAC1_done - - // If FAC1 is 0, just copy FAC2 to FAC1 - - lda FAC1_exponent - beq_16 mov_FAC2_FAC1 - - // Make sure the exponents are aligned - - jsr add_align_exponents - - // Check whether signs are the same - - lda FAC1_sign - eor FAC2_sign - - bmi add_FAC2_FAC1_sub // branch if signs are opposite - - - - - -add_FAC2_FAC1_sub: - - STUB_IMPLEMENTATION() - - -add_FAC2_FAC1_done: - - rts \ No newline at end of file diff --git a/c64/basic/math/b86a.add_FAC2_FAC1.s b/c64/basic/math/b86a.add_FAC2_FAC1.s new file mode 100644 index 00000000..4565af0b --- /dev/null +++ b/c64/basic/math/b86a.add_FAC2_FAC1.s @@ -0,0 +1,114 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add FAC2 to FAC1 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 112 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX test this + +add_FAC2_FAC1: + + // Check if FAC2 is 0; if so leave FAC1 without changes + + lda FAC2_exponent + beq add_FAC2_FAC1_done + + // If FAC1 is 0, if so just copy FAC2 to FAC1 + + lda FAC1_exponent + beq_16 mov_FAC2_FAC1 + + // Make sure the exponents are aligned + + jsr add_align_exponents + + // Check whether signs are the same + + lda FAC1_sign + eor FAC2_sign + + bmi add_FAC2_FAC1_sub // branch if signs are opposite + + // Perform the addition + + clc + lda FAC2_mantissa+3 + adc FAC1_mantissa+3 + sta FAC1_mantissa+3 + + lda FAC2_mantissa+2 + adc FAC1_mantissa+2 + sta FAC1_mantissa+2 + + lda FAC2_mantissa+1 + adc FAC1_mantissa+1 + sta FAC1_mantissa+1 + + lda FAC2_mantissa+0 + adc FAC1_mantissa+0 + sta FAC1_mantissa+0 + + bcc add_FAC2_FAC1_normalize // end if no need to adapt the exponent + + inc FAC1_exponent + bne add_FAC2_FAC1_normalize // end if no overflow + + // Overflow - XXX shouldnt we mark it somewhere in memory? + + lda #$FF + sta FAC1_exponent + sta FAC1_mantissa+3 + sta FAC1_mantissa+2 + sta FAC1_mantissa+1 + sta FAC1_mantissa+0 + + // FALLTROUGH + +add_FAC2_FAC1_done: + + rts + +add_FAC2_FAC1_sub: + + // Perform the subtration + + sec + lda FAC1_mantissa+3 + sbc FAC2_mantissa+3 + sta FAC1_mantissa+3 + + lda FAC1_mantissa+2 + sbc FAC2_mantissa+2 + sta FAC1_mantissa+2 + + lda FAC1_mantissa+1 + sbc FAC2_mantissa+1 + sta FAC1_mantissa+1 + + lda FAC1_mantissa+0 + sbc FAC2_mantissa+0 + sta FAC1_mantissa+0 + + bcs add_FAC2_FAC1_normalize // end if no need to adapt the exponent + + dec FAC1_exponent + + // FALLTROUGH + +add_FAC2_FAC1_normalize: + + jmp normal_FAC1 diff --git a/c64/basic/,stubs_math/b86a.interop b/c64/basic/math/b86a.interop similarity index 100% rename from c64/basic/,stubs_math/b86a.interop rename to c64/basic/math/b86a.interop From c1335b908f1d0f93682b234125c9645634fce2c7 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 14 Feb 2020 19:25:53 +0100 Subject: [PATCH 53/66] fixes for floating point subtraction --- c64/basic/math/add_FAC2_FAC1_sub.s | 107 +++++++++++++++++++++++++ c64/basic/math/b86a.add_FAC2_FAC1.s | 31 +------ c64/basic/math/bfb4.toggle_sign_FAC1.s | 4 + 3 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 c64/basic/math/add_FAC2_FAC1_sub.s diff --git a/c64/basic/math/add_FAC2_FAC1_sub.s b/c64/basic/math/add_FAC2_FAC1_sub.s new file mode 100644 index 00000000..24d20618 --- /dev/null +++ b/c64/basic/math/add_FAC2_FAC1_sub.s @@ -0,0 +1,107 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - add FAC2 to FAC1, subtraction part +// + +// XXX test this + +add_FAC2_FAC1_sub: + + // First verify that |FAC1| > |FAC2|, branch to proper variant if it is not + // Note, that exponents are laready equalized + + lda FAC1_mantissa+0 + cmp FAC2_mantissa+0 + bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch + bne !+ // if FAC1 > FAC2, branch + + lda FAC1_mantissa+1 + cmp FAC2_mantissa+1 + bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch + bne !+ // if FAC1 > FAC2, branch + + lda FAC1_mantissa+2 + cmp FAC2_mantissa+2 + bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch + bne !+ // if FAC1 > FAC2, branch + + lda FAC1_mantissa+3 + cmp FAC2_mantissa+3 + bcc add_FAC2_FAC1_sub_rev // if FAC1 < FAC2, branch + bne !+ // if FAC1 > FAC2, branch + + // If we are here, than FAC1 is equal to FAC2 - so just set FAC1 to 0 + + lda #$00 + sta FAC1_exponent + rts +!: + // Perform the subtration, FAC1 = FAC1 - FAC2 + + sec + lda FAC1_mantissa+3 + sbc FAC2_mantissa+3 + sta FAC1_mantissa+3 + + lda FAC1_mantissa+2 + sbc FAC2_mantissa+2 + sta FAC1_mantissa+2 + + lda FAC1_mantissa+1 + sbc FAC2_mantissa+1 + sta FAC1_mantissa+1 + + lda FAC1_mantissa+0 + sbc FAC2_mantissa+0 + sta FAC1_mantissa+0 + + bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent + + dec FAC1_exponent + + jmp normal_FAC1 + +add_FAC2_FAC1_sub_rev: + + // Since |FAC1| < |FAC2|, toggle FAC1 sign before subtraction + + jsr toggle_sign_FAC1_skipcheck + + // Perform the subtration, FAC1 = FAC2 - FAC1 + + sec + lda #$00 + sbc FACOV + sta FACOV + + lda FAC2_mantissa+3 + sbc FAC1_mantissa+3 + sta FAC1_mantissa+3 + + lda FAC2_mantissa+2 + sbc FAC1_mantissa+2 + sta FAC1_mantissa+2 + + lda FAC2_mantissa+1 + sbc FAC1_mantissa+1 + sta FAC1_mantissa+1 + + lda FAC2_mantissa+0 + sbc FAC1_mantissa+0 + sta FAC1_mantissa+0 + + bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent + + lda FAC2_exponent + sta FAC1_exponent + dec FAC1_exponent + + // FALLTROUGH + +add_FAC2_FAC1_sub_normalize: + + jmp normal_FAC1 diff --git a/c64/basic/math/b86a.add_FAC2_FAC1.s b/c64/basic/math/b86a.add_FAC2_FAC1.s index 4565af0b..7ed3aa98 100644 --- a/c64/basic/math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/math/b86a.add_FAC2_FAC1.s @@ -41,7 +41,7 @@ add_FAC2_FAC1: lda FAC1_sign eor FAC2_sign - bmi add_FAC2_FAC1_sub // branch if signs are opposite + bmi_16 add_FAC2_FAC1_sub // branch if signs are opposite // Perform the addition @@ -66,8 +66,6 @@ add_FAC2_FAC1: inc FAC1_exponent bne add_FAC2_FAC1_normalize // end if no overflow - - // Overflow - XXX shouldnt we mark it somewhere in memory? lda #$FF sta FAC1_exponent @@ -82,33 +80,6 @@ add_FAC2_FAC1_done: rts -add_FAC2_FAC1_sub: - - // Perform the subtration - - sec - lda FAC1_mantissa+3 - sbc FAC2_mantissa+3 - sta FAC1_mantissa+3 - - lda FAC1_mantissa+2 - sbc FAC2_mantissa+2 - sta FAC1_mantissa+2 - - lda FAC1_mantissa+1 - sbc FAC2_mantissa+1 - sta FAC1_mantissa+1 - - lda FAC1_mantissa+0 - sbc FAC2_mantissa+0 - sta FAC1_mantissa+0 - - bcs add_FAC2_FAC1_normalize // end if no need to adapt the exponent - - dec FAC1_exponent - - // FALLTROUGH - add_FAC2_FAC1_normalize: jmp normal_FAC1 diff --git a/c64/basic/math/bfb4.toggle_sign_FAC1.s b/c64/basic/math/bfb4.toggle_sign_FAC1.s index c73ed745..d3fa428a 100644 --- a/c64/basic/math/bfb4.toggle_sign_FAC1.s +++ b/c64/basic/math/bfb4.toggle_sign_FAC1.s @@ -16,6 +16,10 @@ toggle_sign_FAC1: lda FAC1_exponent beq !+ // do not toggle the sign if value is 0 + // FALLTROUGH + +toggle_sign_FAC1_skipcheck: // entry for other routines + lda FAC1_sign eor #$FF sta FAC1_sign From 830711867720d0dbd7b112ae1b823989651f1573 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 14 Feb 2020 22:11:03 +0100 Subject: [PATCH 54/66] updated license/authors --- CONTRIBUTORS.md | 2 +- LICENSE | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c2bcde66..902f47aa 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,3 @@ -Although the project itself is LGPL3, I (FeralChild64 - Roman St********ski) allow to redistribute +Although the project itself is LGPL3, I (FeralChild64 - Roman Standzikowski) allow to redistribute my contributions to this project under any OSI (Open Source Initiative) approved open source license. diff --git a/LICENSE b/LICENSE index d309cbde..e7be5d84 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,8 @@ The following copyright notices apply to the entirety of this package, including each source file, unless otherwise noted in each file. - Copyright Paul Gardner-Stephen, 2019. + Copyright Paul Gardner-Stephen, 2019. + Copyright Roman Standzikowski (FeralChil64), 2019-2020. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by From ad70af9d737dfc9654f7e1effac33c07d3ba2b69 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 16 Feb 2020 15:50:04 +0100 Subject: [PATCH 55/66] tape wedge fix --- c64/basic/basic_main_loop.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c64/basic/basic_main_loop.s b/c64/basic/basic_main_loop.s index 8e880687..575a98e5 100644 --- a/c64/basic/basic_main_loop.s +++ b/c64/basic/basic_main_loop.s @@ -81,7 +81,7 @@ rsl_l1: beq_16 wedge_dos #endif #if CONFIG_TAPE_WEDGE - cmp #$1F // left arrow + cmp #$5F // left arrow beq_16 wedge_tape #endif From 586ee998c69ed2276ad9ed71404312a6dd6dd07a Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 16 Feb 2020 16:18:19 +0100 Subject: [PATCH 56/66] adding of floating point values works now --- STATUS.md | 10 +++++----- c64/basic/math/b86a.add_FAC2_FAC1.s | 15 +++++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/STATUS.md b/STATUS.md index 49b5c4c7..7c20cb47 100644 --- a/STATUS.md +++ b/STATUS.md @@ -191,22 +191,22 @@ Floating point mathematical routines - not official, but well known and broadly | `$B849` | `add_HALF_FAC1` | NOT DONE | | | `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B862` | `add_align_exponents` | PARTIAL | not tested yet | +| `$B862` | `add_align_exponents` | DONE | | | `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B86A` | `add_FAC2_FAC1` | PARTIAL | not tested yet | -| `$B8FE` | `normal_FAC1` | PARTIAL | not tested yet | +| `$B86A` | `add_FAC2_FAC1` | PARTIAL | aubstration not tested yet | +| `$B8FE` | `normal_FAC1` | PARTIAL | not fully tested yet | | `$B947` | `inv_FAC1_mantissa` | NOT DONE | | | `$B983` | `MULSHF` | NOT DONE | | | `$B9EA` | `log_FAC1` | NOT DONE | | | `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | | `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | | `$BA59` | `MLTPLY` | NOT DONE | | -| `$BA8C` | `mov_MEM_FAC2` | PARTIAL | not fully tested yet | +| `$BA8C` | `mov_MEM_FAC2` | DONE | | | `$BAE2` | `mul10_FAC1` | NOT DONE | | | `$BAFE` | `div10_FAC1_p` | NOT DONE | | | `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | | `$BB12` | `div_FAC2_FAC1` | NOT DONE | | -| `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | +| `$BBA2` | `mov_MEM_FAC1` | DONE | | | `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | | `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | | `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | diff --git a/c64/basic/math/b86a.add_FAC2_FAC1.s b/c64/basic/math/b86a.add_FAC2_FAC1.s index 7ed3aa98..1e6bf6b9 100644 --- a/c64/basic/math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/math/b86a.add_FAC2_FAC1.s @@ -62,10 +62,10 @@ add_FAC2_FAC1: adc FAC1_mantissa+0 sta FAC1_mantissa+0 - bcc add_FAC2_FAC1_normalize // end if no need to adapt the exponent + bcc_16 normal_FAC1 // end if no need to adapt the exponent inc FAC1_exponent - bne add_FAC2_FAC1_normalize // end if no overflow + bne add_FAC2_FAC1_adapt_mantissa // end if no overflow lda #$FF sta FAC1_exponent @@ -80,6 +80,13 @@ add_FAC2_FAC1_done: rts -add_FAC2_FAC1_normalize: +add_FAC2_FAC1_adapt_mantissa: + + sec + ror FAC1_mantissa+0 + ror FAC1_mantissa+1 + ror FAC1_mantissa+2 + ror FAC1_mantissa+3 + ror FACOV - jmp normal_FAC1 + rts From 391f489dfd7b29d5e744661c3aa1de5ccf40084b Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 16 Feb 2020 16:51:08 +0100 Subject: [PATCH 57/66] fixed sign on moving floating point values --- c64/basic/math/mov_MEM_FAC1.s | 4 ++-- c64/basic/math/mov_MEM_FAC2.s | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/c64/basic/math/mov_MEM_FAC1.s b/c64/basic/math/mov_MEM_FAC1.s index 39296f87..6de5b9c8 100644 --- a/c64/basic/math/mov_MEM_FAC1.s +++ b/c64/basic/math/mov_MEM_FAC1.s @@ -22,7 +22,7 @@ // XXX test this mov_MEM_FAC1: - +.break // Original routines use $22/$23 location for a vector too, see here: // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics @@ -58,7 +58,7 @@ mov_MEM_FAC1: lda #$FF skip_2_bytes_trash_nvz !: - lda $00 + lda #$00 sta FAC1_sign diff --git a/c64/basic/math/mov_MEM_FAC2.s b/c64/basic/math/mov_MEM_FAC2.s index 8102794d..f461a667 100644 --- a/c64/basic/math/mov_MEM_FAC2.s +++ b/c64/basic/math/mov_MEM_FAC2.s @@ -61,7 +61,7 @@ mov_MEM_FAC2: lda #$FF skip_2_bytes_trash_nvz !: - lda $00 + lda #$00 sta FAC2_sign From 00fdc397c0eaa51bd1e605a34cd67a52eeee6e09 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 17 Feb 2020 16:38:23 +0100 Subject: [PATCH 58/66] added ccredits --- CREDITS.md | 33 +++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 CREDITS.md diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 00000000..7c8eb371 --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,33 @@ + +# CREDITS to people whose work was of great help to us + +
    + +## For source code we reused + +
    + +* TWW/CTR - for his keyboard handling code +* Graham - for his PAL/NTSC detection routine +* enthusi/Onslaught - for his example Turbo Tape 64 compatible loader + +
    + +## For documentation + +
    + +* Frantic - for [Codebase 64](https://codebase64.org) +* Joe Forster/STA - for the official/unofficial ROM API description at [sta.c64.org](http://sta.c64.org) +* J. Derogee - for the IEC Disected document +* Michael Steil - for a great IEC protocol description and various other documentation at [his blog](https://www.pagetable.com) +* Jochen Adler - for the JiffyDOS protocol reverse engineering +* H2Obsession - for the JiffyDOS protocol description on [his page](https://sites.google.com/site/h2obsession/CBM/C128/JiffySoft128) +* SD2IEC team - the project [source code](https://github.com/rkrajnc/sd2iec) helped a lot when adding IEC and JiffyDOS support +* slark - for his screen codes / PETSCII description at [slark.me](https://slark.me) +* silverdr - for the floating point routines [description](https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics) +* the [C64 Wiki](https://www.c64-wiki.com) contributors + +
    + +* ... and all the others we forgot diff --git a/README.md b/README.md index 9a966ccb..4f8186b0 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ A project to create unencumbered open-source ROMs for use on selected retro comp * [implementation status](./STATUS.md) of various APIs and functionalities * [configuration options](./CONFIG.md) for those willing to compile their own, customized ROM set * [development guide](./doc/Development.md) for those interested in OpenROMs technical aspects +* [license](./LICENSE) information and list of major contributors +* [credits](./CREDITS.md) to people whose work was of great help to us # Problem Statement and Motivation From 79da285575f4b8278e7112233e1d09ce17ea74c0 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 17 Feb 2020 17:19:32 +0100 Subject: [PATCH 59/66] fix for floating point subtraction, started work on multiplication --- STATUS.md | 2 +- c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s | 24 ------ c64/basic/math/add_FAC2_FAC1_sub.s | 16 +--- c64/basic/math/b86a.add_FAC2_FAC1.s | 4 + c64/basic/{,stubs_math => math}/ba2b.interop | 0 c64/basic/math/ba2b.mul_FAC2_FAC1.s | 8 ++ c64/basic/math/mov_MEM_FAC1.s | 2 +- c64/basic/math/mul_FAC2_FAC1.s | 90 ++++++++++++++++++++ 8 files changed, 107 insertions(+), 39 deletions(-) delete mode 100644 c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s rename c64/basic/{,stubs_math => math}/ba2b.interop (100%) create mode 100644 c64/basic/math/ba2b.mul_FAC2_FAC1.s create mode 100644 c64/basic/math/mul_FAC2_FAC1.s diff --git a/STATUS.md b/STATUS.md index 7c20cb47..69d469e1 100644 --- a/STATUS.md +++ b/STATUS.md @@ -199,7 +199,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B983` | `MULSHF` | NOT DONE | | | `$B9EA` | `log_FAC1` | NOT DONE | | | `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | -| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | +| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | some work started | | `$BA59` | `MLTPLY` | NOT DONE | | | `$BA8C` | `mov_MEM_FAC2` | DONE | | | `$BAE2` | `mul10_FAC1` | NOT DONE | | diff --git a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s deleted file mode 100644 index f6659b85..00000000 --- a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s +++ /dev/null @@ -1,24 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - multiplies FAC1 by FAC2 -// -// Input: -// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag -// -// Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -mul_FAC2_FAC1: - STUB_IMPLEMENTATION() diff --git a/c64/basic/math/add_FAC2_FAC1_sub.s b/c64/basic/math/add_FAC2_FAC1_sub.s index 24d20618..a045e1b8 100644 --- a/c64/basic/math/add_FAC2_FAC1_sub.s +++ b/c64/basic/math/add_FAC2_FAC1_sub.s @@ -12,7 +12,7 @@ add_FAC2_FAC1_sub: // First verify that |FAC1| > |FAC2|, branch to proper variant if it is not - // Note, that exponents are laready equalized + // We ignore FACOV here. Note, that exponents are already equalized lda FAC1_mantissa+0 cmp FAC2_mantissa+0 @@ -59,9 +59,7 @@ add_FAC2_FAC1_sub: sbc FAC2_mantissa+0 sta FAC1_mantissa+0 - bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent - - dec FAC1_exponent + // Exponent should never need adaptation here jmp normal_FAC1 @@ -94,14 +92,6 @@ add_FAC2_FAC1_sub_rev: sbc FAC1_mantissa+0 sta FAC1_mantissa+0 - bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent - - lda FAC2_exponent - sta FAC1_exponent - dec FAC1_exponent - - // FALLTROUGH - -add_FAC2_FAC1_sub_normalize: + // Exponent should never need adaptation here jmp normal_FAC1 diff --git a/c64/basic/math/b86a.add_FAC2_FAC1.s b/c64/basic/math/b86a.add_FAC2_FAC1.s index 1e6bf6b9..9ae04a29 100644 --- a/c64/basic/math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/math/b86a.add_FAC2_FAC1.s @@ -67,6 +67,10 @@ add_FAC2_FAC1: inc FAC1_exponent bne add_FAC2_FAC1_adapt_mantissa // end if no overflow + // FALLTROUGH + +set_FAC1_max: // entry used by other routines too + lda #$FF sta FAC1_exponent sta FAC1_mantissa+3 diff --git a/c64/basic/,stubs_math/ba2b.interop b/c64/basic/math/ba2b.interop similarity index 100% rename from c64/basic/,stubs_math/ba2b.interop rename to c64/basic/math/ba2b.interop diff --git a/c64/basic/math/ba2b.mul_FAC2_FAC1.s b/c64/basic/math/ba2b.mul_FAC2_FAC1.s new file mode 100644 index 00000000..1b918524 --- /dev/null +++ b/c64/basic/math/ba2b.mul_FAC2_FAC1.s @@ -0,0 +1,8 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mul_FAC2_FAC1 diff --git a/c64/basic/math/mov_MEM_FAC1.s b/c64/basic/math/mov_MEM_FAC1.s index 6de5b9c8..f99cb9ee 100644 --- a/c64/basic/math/mov_MEM_FAC1.s +++ b/c64/basic/math/mov_MEM_FAC1.s @@ -22,7 +22,7 @@ // XXX test this mov_MEM_FAC1: -.break + // Original routines use $22/$23 location for a vector too, see here: // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics diff --git a/c64/basic/math/mul_FAC2_FAC1.s b/c64/basic/math/mul_FAC2_FAC1.s new file mode 100644 index 00000000..35b71b39 --- /dev/null +++ b/c64/basic/math/mul_FAC2_FAC1.s @@ -0,0 +1,90 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - multiplies FAC1 by FAC2 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +mul_FAC2_FAC1: + + // First handle special case of multiplying by 0 + + lda FAC1_exponent + beq mul_FAC2_FAC1_done + + lda FAC2_exponent + bne !+ + sta FAC1_exponent + beq mul_FAC2_FAC1_done +!: + // Multiply signs + + lda FAC1_sign + eor FAC2_sign + sta FAC1_sign + + // Check if exponents can be added without overflow/underflow + + lda FAC1_exponent + and #$80 + eor FAC2_exponent + + bmi mul_FAC2_FAC1_add_exponents // exponent signs are opposite, we can add them safely + + // Both exponents are either negative (below $80), or both are non-negative ($80 or above), + // try to add them + + lda FAC1_exponent + clc + adc FAC2_exponent + bpl mul_FAC2_FAC1_sub_exp_bias // branch if we can add values + + // We cannot add them, result would over/underflow; set result as + // either 0 or maximum possible float + + lda FAC1_exponent + bmi_16 set_FAC1_max + + lda #$00 + sta FAC1_exponent + rts + +mul_FAC2_FAC1_add_exponents: + + // Add the exponents + + lda FAC1_exponent + clc + adc FAC2_exponent + + // FALLTROUGH + +mul_FAC2_FAC1_sub_exp_bias: + + sec + sbc #$80 // bias + sta FAC1_exponent + + // Multiply the mantissas + + // XXX + + STUB_IMPLEMENTATION() + +mul_FAC2_FAC1_done: + + rts From 6fa7eb2aa92a7cb73169a2ebb1bc869f9412e04f Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 17 Feb 2020 17:44:06 +0100 Subject: [PATCH 60/66] updated documentation and binaries --- CREDITS.md | 12 ++---------- STATUS.md | 10 +++++----- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes ...mul_MEM_FAC1.s => ba28.mul_MEM_FAC1.jmp.s} | 0 10 files changed, 7 insertions(+), 15 deletions(-) rename c64/basic/math/{ba28.mul_MEM_FAC1.s => ba28.mul_MEM_FAC1.jmp.s} (100%) diff --git a/CREDITS.md b/CREDITS.md index 7c8eb371..72143f5f 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,21 +1,13 @@ # CREDITS to people whose work was of great help to us -
    - -## For source code we reused - -
    +## for source code we reused * TWW/CTR - for his keyboard handling code * Graham - for his PAL/NTSC detection routine * enthusi/Onslaught - for his example Turbo Tape 64 compatible loader -
    - -## For documentation - -
    +## for documentation * Frantic - for [Codebase 64](https://codebase64.org) * Joe Forster/STA - for the official/unofficial ROM API description at [sta.c64.org](http://sta.c64.org) diff --git a/STATUS.md b/STATUS.md index 69d469e1..53a24135 100644 --- a/STATUS.md +++ b/STATUS.md @@ -189,12 +189,12 @@ Floating point mathematical routines - not official, but well known and broadly | `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | | `$B7F7` | `convert_FAC1_to_ADDR` | NOT DONE | | | `$B849` | `add_HALF_FAC1` | NOT DONE | | -| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | +| `$B850` | `sub_MEM_FAC1` | DONE | | +| `$B853` | `sub_FAC2_FAC1` | DONE | | | `$B862` | `add_align_exponents` | DONE | | -| `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | -| `$B86A` | `add_FAC2_FAC1` | PARTIAL | aubstration not tested yet | -| `$B8FE` | `normal_FAC1` | PARTIAL | not fully tested yet | +| `$B867` | `add_MEM_FAC1` | DONE | | +| `$B86A` | `add_FAC2_FAC1` | DONE | | +| `$B8FE` | `normal_FAC1` | DONE | | | `$B947` | `inv_FAC1_mantissa` | NOT DONE | | | `$B983` | `MULSHF` | NOT DONE | | | `$B9EA` | `log_FAC1` | NOT DONE | | diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index a6b3a27e12b5bab2a0119ccabf451ae57bca33e5..7db8844e80da01eaa0643a6b6be8327928f7a332 100644 GIT binary patch delta 592 zcmXYvOK1~O6ozLePnEU_QXQK_M--$qXl)Bd&7um0A_J}@AZq7zhsjH`5pk6fy_ki_ z$fYYO#MoPnke4x76H46#O;)q$svAqoh>BuR5p>adGkCa*pToyFKmWPV}yUrhddCL`Z&zTPXcoVI;zV|zA_g8dzWTL+1>AI(i6x6sc<$|Xn&BwaFKSYz4 zcN8eLA>EA4OP_MS-&h0JpoTS*VFhlxj9#(hSuC{^##u9j<#y7TG>5U$P8nn700!-} zal~|y!J-hsz)C}a6)Oc5EL%w^W64TDiO;TZ%d3$hWo2Lnr!7FBl%)_TX~_giSdtA< zqy$oVs&Iv0Yf%CheclQ8c6E?3vZ&xBG3@_@L#Fb+X3r zY{AK{Q1tC+b%FZNe5;_pgCY7CVu$3~z9?PC{`c;S=deg3T5oap7O^^W-RI!_6&9y~ zZ4218fNcv9TU7^f|4}ptiaSt*04h+1k`PfPRaO-hs2Smr|2*1eFPz3=ZwkjvClq_( z{#>YHaa5m)kMG4I3*tUM7Rjoo%XU_FEAm+n*NSMppxe8FDQ>aLLu!28U?!JL+cWAx)n`bBCV%1DXW_>;M1& delta 359 zcmZp0XmHq&$-=aD-Q;{WiOJ0@pFqrV)^IlY3(P)SA5Ff(`W_^5lQi&!M~GB8&9t)I&PRr7z{ ztuzlA$$2VegJb z>|2wjhMyAn31kD&0_H^w5?hl>!>1;_=n(j}G$S>xHDhVU1ty6Eg^N2TKjbr*C@3}g zpM=*$LF>udGJKOiNO4Y7P@23)GG9MoY2pW^r3C^~&r&alJxjSD^ep)T-?O9(Tq_$| zlb$7BU^g@7~+BNx> xw6P$N)xK`ot_K_&m=J7``9T`0b6=8jaf1PApd2xmhsNt+;&)yiN$78$x9 zcMWWV>kfsDQkG?&G*?Z$N#<(RwEmdGTX4JE3WJWZtq@noC>Qnt+raEibg;wap2NA% z^FHT&pZDCU?x}8V$ik&>CPyqHTXKCtA24`)Y#GHO(XzUyE=O)~Y~Y^on-AL}fk2>WZBqHc7d)&_DpkE9i#^4#ufG+!!R%o=BINI~ zdhSGo)RezMu9rXCTd(Rzl%t?+1#KSJtMtCn5EIy_jg_tF!zeA#1%=16VRT+qYQM0t z#wvWBuV7OQ_W{E_u3#SvEKWtp0m0!&MN~$%%Eh!mE}1C~Tepg7vHl&@VqPVELKD}g zk~f5E>wD_^cG0PlpKA9fKP%j}90!&U{SpgV7v0w`-V^?UH9SE+#Ml?zuU)+6eiRV? zq(14A?4v$|vx{gaMn18(O;Y#zu+nAJQ_uQ{(r#4I!Szw4#VDoH`k3;Bkq3cYqLWJL zFd0)t`U3i1 zL#Yf}%Ro85(a_HsbnI7jNQ*L@-ewF$+3fTZ-qg^86v6p6}m)3MW16T4m9WpGk%WTbtm%Y^0Jau}gZ69^nr6IvaU7+~!Qm)-{Th8q% z=sc0US#vIX%fG7WKZ1L2gI?#4oSCgd)^D6!0qItd4Ozj8nbvR%K6{7s<##0CsXfV- zG$(>*Lub(9L);%G4;<|_SY3_L7Wp~aDxVPX;zRhW1X-2bt@C7c8tZ4XlTp9_@LXKs m@$GQ7RS)HKs9#>86Y}crPPxv2yN*P%wBbdT?H~gOKKd8yiVc(i delta 974 zcmYjQZ)jUp6urrbXRrx=KXUB8b?1 zXh4ENr>0y6Rw=~bOJ3@lyd-psX`}rhV|Orpm4R%q4^tXD(DCpe=%Deu6~V*f-OIV> zp5O1B^SjBRY|| zMY&0Ofe324z|U3-d@0y-aJ66z|966{qhc!4<(q5H>9J-}k3pO&sI^HTYp*zDIoQR# zeU<3EQ&tJlYp=^axb}_rPRHKZd$A(QI%g10OaCOYAxN|(mLp1&;I|K!X9-SUm3~jK z8ztW52}Op>vk-XS(=MfL^DR$hZsi0VD&R|i@4r%+v-5g3sy-+v(zP)Dt0Wd|BZ)8>4Xald> zTapjgrXP?xWDvwAU_iZ}15G2(k~*)2juDW{z0gsZIUiE?9}jAyrh{EuqHlbqz4Z8N zQ5a1Tr4qDR&$$=k=TBXg{)Rn#Sw{{j3-LEkosX}jrN6Yq_=~B8mN1E;(v>>D-4&e< zhWWbEX=m>29-Iyi@^`wKE%cS{kpn7dd$%?rgBuR5p>adGkCa*pToyFKmWPV}yUrhddCL`Z&zTPXcoVI;zV|zA_g8dzWTL+1>AI(i6x6sc<$|Xn&BwaFKSYz4 zcN8eLA>EA4OP_MS-&h0JpoTS*VFhlxj9#(hSuC{^##u9j<#y7TG>5U$P8nn700!-} zal~|y!J-hsz)C}a6)Oc5EL%w^W64TDiO;TZ%d3$hWo2Lnr!7FBl%)_TX~_giSdtA< zqy$oVs&Iv0Yf%CheclQ8c6E?3vZ&xBG3@_@L#Fb+X3r zY{AK{Q1tC+b%FZNe5;_pgCY7CVu$3~z9?PC{`c;S=deg3T5oap7O^^W-RI!_6&9y~ zZ4218fNcv9TU7^f|4}ptiaSt*04h+1k`PfPRaO-hs2Smr|2*1eFPz3=ZwkjvClq_( z{#>YHaa5m)kMG4I3*tUM7Rjoo%XU_FEAm+n*NSMppxe8FDQ>aLLu!28U?!JL+cWAx)n`bBCV%1DXW_>;M1& delta 359 zcmZp0XmHq&$-=aD-Q;{WiOJ0@pFqrV)^IlY3(P)SA5Ff(`W_^5lQi&!M~GB8&9t)I&PRr7z{ ztuzlA$$2VegJb z>|2wjhMyAn31kD&0_H^w5?hl>!>1;_=n(j}G$S>xHDhVU1ty6Eg^N2TKjbr*C@3}g zpM=*$LF>udGJKOiNO4Y7P@23)GG9MoY2pW^r3C^~&r&alJxjSD^ep)T-?O9(Tq_$| zlb$7BU^g@7~+BNx> xw6P$N)xK`ot_K_&m=Hq)$ delta 78 zcmZp0XmHrDl}UZ&|5mF9OdptiG#{^JWIE{sX02ps-M)Zv5xc^!|4Ve1Y5Rz8ntX?8 iGSk|1lM9*6m^Ln-ypnky3;6Y diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index 7bd2be849d7edf40f59963f6f9ec396cea0a657c..cee5e14c90dda0e2a4fe67f2566f3bfc98b2ecc4 100644 GIT binary patch delta 77 zcmV-T0J8spK!8B7wE`!lVelfQa1a{iWzZJpWY7}kW6%!fV$ceyfQ4e_VbB7`VW|Lx jaA1?%0?Yxrlc@uG0Hq)$ delta 78 zcmZp0XmHrDl}UZ&|5mF9OdptiG#{^JWIE{sX02ps-M)Zv5xc^!|4Ve1Y5Rz8ntX?8 iGSk|1lM9*6m^Ln-ypnky3;6Y diff --git a/bin/mega65.rom b/bin/mega65.rom index 7bb1ae23ce52b64088521675fdfdbb9fefba5b30..d5cb39780710dcee12422e9c4dcf74bd8c3ab1f3 100644 GIT binary patch delta 931 zcmchW-)~c87{|{k+bqi5b}=bVk|PU2eg?M-3Nyx#5T-eIL`?|dIc-m~tt-}_h&oz? zmz5u4=fgl5!&&=oYh`VhW~}S!7#D1z3m1(sUU(zBJj!D0bI&D@z;r5!*m2bDT3-yi^{}(BWJQEsWd>`p^wO zj^RB7@IF4k)yd0~AL1i?j8Aaiyq`agPmvfufzR+czCaI7B8X=fYNkT?ck&dz#A!%V zXTWe4y$ItR&f@|u;wxOj*NC7G-+*u#{kVdw_!i&c8U}D3gSdh3F@zt2h~h`Yz%h&w zj3SN%e!@+R{ZFS)-kG@@e^~WgTw)!{qh$1{30MEy^YzOj7nio0FWAaSI%w_=a@TBE zq^-D-yJvlo)?y>~%yvh%7i+mO>yI=StA&EDIk{o^nZZ3)H}i0}vgzgK z^q@@+&(|+?sB@`sIQ;aTVC46Xp)G}Aq_I6(<(QV_6K&~1=?U{!ik6cb0h{aN*gUaXC;Fr699!`#fJ zIlV5g+w1Wf-T?XVI+e3$_i}x)g?ARKn7+7eRg-zSzBP29b9V#R9Y$w;9oJj`E?1gV z`EWiAiGFF)sXloF{W|sLI`zy{oRpte;_jg|-Nq(aqw$fJHR|S4pL~e&iS@Lcd)`sl zRjlK6g_T8{Lla_kYRGhGO0P**vfJ!qNl_|eNxGMPv9X*~UK>?kH3b&6_v`cZk6Az? zGWSTbGBVM+FaTsq}oe8@}ARk LrOCOHyszm$s}=WE delta 720 zcmchV-%C?*7{WP^s>6y0i$Ur8xV+XR34K1EU zopDDuc$X@J&0B)ujB`8H1%CR36IDkr2 zp&CZipcV&FhkBUMfJQXo5Sr0~RqNz(Z6wd^PSekF?B2P+IQNg)@YCl& z5z~++*r(z+8VZz!uLV1qOSce~LJR4YTB(1{suqSN=|<>I_SS?G9S@kSNQ&5!mk>Hauwi?k7aNVC2ccHhMc z=-tdEdX+G$IZmXI$E3EDr(EnJ#eMm-9xH5A{H?-y*}ZLQV6=Nlx2|YqC)93EKQ(Z- zdvxH7Q};`v-kXpAvSPmDgu4LOQ>6SVr5PZGt-0lRAfHI+6;dIFr`ML diff --git a/c64/basic/math/ba28.mul_MEM_FAC1.s b/c64/basic/math/ba28.mul_MEM_FAC1.jmp.s similarity index 100% rename from c64/basic/math/ba28.mul_MEM_FAC1.s rename to c64/basic/math/ba28.mul_MEM_FAC1.jmp.s From 5d887217df57ae6b84b4d257e18ffb9a2b8ec1cf Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 18 Feb 2020 15:59:22 +0100 Subject: [PATCH 61/66] added few more floating point stubs --- STATUS.md | 3 +++ .../,stubs_math/b1bf.convert_FAC1_to_s16.s | 17 +++++++++++++++++ c64/basic/,stubs_math/b1bf.interop | 4 ++++ c64/basic/,stubs_math/ba90.get_FAC2_via_INDEX.s | 17 +++++++++++++++++ c64/basic/,stubs_math/ba90.interop | 4 ++++ c64/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s | 17 +++++++++++++++++ c64/basic/,stubs_math/bba6.interop | 4 ++++ 7 files changed, 66 insertions(+) create mode 100644 c64/basic/,stubs_math/b1bf.convert_FAC1_to_s16.s create mode 100644 c64/basic/,stubs_math/b1bf.interop create mode 100644 c64/basic/,stubs_math/ba90.get_FAC2_via_INDEX.s create mode 100644 c64/basic/,stubs_math/ba90.interop create mode 100644 c64/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s create mode 100644 c64/basic/,stubs_math/bba6.interop diff --git a/STATUS.md b/STATUS.md index 53a24135..4597818f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -183,6 +183,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$AF87` | not named yet | NOT DONE | | | `$AF9A` | `compute_ST` | NOT DONE | | | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | +| `$B1BF` | `convert_FAC1_to_s16` | NOT DONE | | | `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | | `$B3A2` | `convert_Y_to_FAC1` | NOT DONE | | | `$B794` | `convert_A_to_FAC1` | NOT DONE | | @@ -202,11 +203,13 @@ Floating point mathematical routines - not official, but well known and broadly | `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | some work started | | `$BA59` | `MLTPLY` | NOT DONE | | | `$BA8C` | `mov_MEM_FAC2` | DONE | | +| `$BA90` | `get_FAC2_via_INDEX` | NOT DONE | | | `$BAE2` | `mul10_FAC1` | NOT DONE | | | `$BAFE` | `div10_FAC1_p` | NOT DONE | | | `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | | `$BB12` | `div_FAC2_FAC1` | NOT DONE | | | `$BBA2` | `mov_MEM_FAC1` | DONE | | +| `$BBA6` | `get_FAC2_via_INDEX` | NOT DONE | | | `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | | `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | | `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | diff --git a/c64/basic/,stubs_math/b1bf.convert_FAC1_to_s16.s b/c64/basic/,stubs_math/b1bf.convert_FAC1_to_s16.s new file mode 100644 index 00000000..601bf5d7 --- /dev/null +++ b/c64/basic/,stubs_math/b1bf.convert_FAC1_to_s16.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// See also: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +// XXX implement, test + +convert_FAC1_to_s16: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/b1bf.interop b/c64/basic/,stubs_math/b1bf.interop new file mode 100644 index 00000000..3de00adc --- /dev/null +++ b/c64/basic/,stubs_math/b1bf.interop @@ -0,0 +1,4 @@ +This is an important floating point math routine, documented in many places. + +It's a part oof the ACME assembler SDK, see: +- https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True diff --git a/c64/basic/,stubs_math/ba90.get_FAC2_via_INDEX.s b/c64/basic/,stubs_math/ba90.get_FAC2_via_INDEX.s new file mode 100644 index 00000000..1e5b639a --- /dev/null +++ b/c64/basic/,stubs_math/ba90.get_FAC2_via_INDEX.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// See also: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +// XXX implement, test + +get_FAC2_via_INDEX: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/ba90.interop b/c64/basic/,stubs_math/ba90.interop new file mode 100644 index 00000000..3de00adc --- /dev/null +++ b/c64/basic/,stubs_math/ba90.interop @@ -0,0 +1,4 @@ +This is an important floating point math routine, documented in many places. + +It's a part oof the ACME assembler SDK, see: +- https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True diff --git a/c64/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s b/c64/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s new file mode 100644 index 00000000..fc6675f6 --- /dev/null +++ b/c64/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s @@ -0,0 +1,17 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - XXX +// +// See also: +// - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +// + +// XXX implement, test + +get_FAC1_via_INDEX: + + STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bba6.interop b/c64/basic/,stubs_math/bba6.interop new file mode 100644 index 00000000..3de00adc --- /dev/null +++ b/c64/basic/,stubs_math/bba6.interop @@ -0,0 +1,4 @@ +This is an important floating point math routine, documented in many places. + +It's a part oof the ACME assembler SDK, see: +- https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True From 103325cc534a0492a5b3307d3da7be556d535a1c Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 18 Feb 2020 16:46:57 +0100 Subject: [PATCH 62/66] started work on pseudorandom number generator --- STATUS.md | 1 + c64/aliases/,aliases_ram_lowmem.s | 2 +- c64/basic/math/e0be.interop | 5 +++ c64/basic/math/e0be.rnd_generate.s | 63 ++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 c64/basic/math/e0be.interop create mode 100644 c64/basic/math/e0be.rnd_generate.s diff --git a/STATUS.md b/STATUS.md index 4597818f..4868d425 100644 --- a/STATUS.md +++ b/STATUS.md @@ -237,6 +237,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BFED` | `exp_FAC1` | NOT DONE | | | `$E043` | `poly1_FAC1` | NOT DONE | | | `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E0BE` | `rnd_generate` | DONE | | | `$E264` | `cos_FAC1` | NOT DONE | | | `$E26B` | `sin_FAC1` | NOT DONE | | | `$E2B4` | `tan_FAC1` | NOT DONE | | diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index fa426b09..f6f9e3ac 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -76,7 +76,7 @@ .label FBUFPT = $71 // $71-$72 -- NOT IMPLEMENTED -- .label CHRGET = $73 // $73-$8A -- NOT IMPLEMENTED -- .label TXTPTR = $7A // $7A-$7B current BASIC statement pointer - .label RNDX = $8B // $8B-$8F -- NOT IMPLEMENTED -- + .label RNDX = $8B // $8B-$8F random number seed // // Page 0 - Kernal area ($90-$FF) diff --git a/c64/basic/math/e0be.interop b/c64/basic/math/e0be.interop new file mode 100644 index 00000000..5c452b05 --- /dev/null +++ b/c64/basic/math/e0be.interop @@ -0,0 +1,5 @@ +This is an important floating point math routine, see: + +- https://www.atarimagazines.com/compute/issue72/random_numbers.php + +XXX - try to find real-life example diff --git a/c64/basic/math/e0be.rnd_generate.s b/c64/basic/math/e0be.rnd_generate.s new file mode 100644 index 00000000..2bc257f7 --- /dev/null +++ b/c64/basic/math/e0be.rnd_generate.s @@ -0,0 +1,63 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// A fast random generator, idea from: +// - https://codebase64.org/doku.php?id=base:32bit_galois_lfsr +// +// Output: +// - FAC1 +// +// See also: +// - https://www.atarimagazines.com/compute/issue72/random_numbers.php +// + +rnd_generate: + + // Generate new 4-byte random number + + asl RNDX+1 + rol RNDX+2 + rol RNDX+3 + rol RNDX+4 + + bcs rnd_generate_copy + + lda RNDX+1 + eor #$B7 + sta RNDX+1 + lda RNDX+2 + eor #$1D + sta RNDX+2 + lda RNDX+3 + eor #$C1 + sta RNDX+3 + lda RNDX+4 + eor #$04 + sta RNDX+4 + + // FALLTROUGH + +rnd_generate_copy: + + // Copy the number to FAC1, order changed on purpose + + lda RNDX+3 + sta FAC1_mantissa+0 + lda RNDX+1 + sta FAC1_mantissa+1 + lda RNDX+2 + sta FAC1_mantissa+2 + lda RNDX+4 + sta FAC1_mantissa+3 + + lda #$00 + sta FACOV + sta FAC1_sign + + lda #$80 + sta FAC1_exponent + sta RNDX+0 // in case someone tries to use the float directly + + jmp normal_FAC1 From de605cd5eeb6a31f18f5d48f8c4516e1454056af Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 18 Feb 2020 21:25:02 +0100 Subject: [PATCH 63/66] random seed initialization added, tweaked sequence generation --- STATUS.md | 1 + c64/basic/board_x16/cx16_stubs.s | 8 +++++++ c64/basic/math/e09a.interop | 5 +++++ c64/basic/math/e09a.rnd_A.s | 26 +++++++++++++++++++++++ c64/basic/math/e0be.rnd_generate.s | 28 ++++++++++++++++-------- c64/basic/math/rnd_seed_from_FAC1.s | 27 +++++++++++++++++++++++ c64/basic/math/rnd_seed_init.s | 33 +++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 c64/basic/board_x16/cx16_stubs.s create mode 100644 c64/basic/math/e09a.interop create mode 100644 c64/basic/math/e09a.rnd_A.s create mode 100644 c64/basic/math/rnd_seed_from_FAC1.s create mode 100644 c64/basic/math/rnd_seed_init.s diff --git a/STATUS.md b/STATUS.md index 4868d425..5ee5f251 100644 --- a/STATUS.md +++ b/STATUS.md @@ -237,6 +237,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BFED` | `exp_FAC1` | NOT DONE | | | `$E043` | `poly1_FAC1` | NOT DONE | | | `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E09A` | `rnd_A` | DONE | | | `$E0BE` | `rnd_generate` | DONE | | | `$E264` | `cos_FAC1` | NOT DONE | | | `$E26B` | `sin_FAC1` | NOT DONE | | diff --git a/c64/basic/board_x16/cx16_stubs.s b/c64/basic/board_x16/cx16_stubs.s new file mode 100644 index 00000000..5b64b03d --- /dev/null +++ b/c64/basic/board_x16/cx16_stubs.s @@ -0,0 +1,8 @@ +// #LAYOUT# X16 BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Stubs for Commander X16 support + + +rnd_seed_init: + jmp rnd_generate diff --git a/c64/basic/math/e09a.interop b/c64/basic/math/e09a.interop new file mode 100644 index 00000000..5c452b05 --- /dev/null +++ b/c64/basic/math/e09a.interop @@ -0,0 +1,5 @@ +This is an important floating point math routine, see: + +- https://www.atarimagazines.com/compute/issue72/random_numbers.php + +XXX - try to find real-life example diff --git a/c64/basic/math/e09a.rnd_A.s b/c64/basic/math/e09a.rnd_A.s new file mode 100644 index 00000000..1bb428f8 --- /dev/null +++ b/c64/basic/math/e09a.rnd_A.s @@ -0,0 +1,26 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Random number generator routine +// +// Input: +// - .A (0 - reinitialize the seed with random value, $80 or above - create seed from FAC1) +// +// Output: +// - FAC1 +// +// See also: +// - https://www.atarimagazines.com/compute/issue72/random_numbers.php +// + +rnd_A: + + cmp #$00 + beq_16 rnd_seed_init + + cmp #$80 + bcc_16 rnd_generate + + jmp rnd_seed_from_FAC1 diff --git a/c64/basic/math/e0be.rnd_generate.s b/c64/basic/math/e0be.rnd_generate.s index 2bc257f7..d315cc1a 100644 --- a/c64/basic/math/e0be.rnd_generate.s +++ b/c64/basic/math/e0be.rnd_generate.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// A fast random generator, idea from: +// A fast pseudorandom generator, modified idea from: // - https://codebase64.org/doku.php?id=base:32bit_galois_lfsr // // Output: @@ -15,8 +15,6 @@ rnd_generate: - // Generate new 4-byte random number - asl RNDX+1 rol RNDX+2 rol RNDX+3 @@ -27,12 +25,15 @@ rnd_generate: lda RNDX+1 eor #$B7 sta RNDX+1 + lda RNDX+2 eor #$1D sta RNDX+2 + lda RNDX+3 eor #$C1 sta RNDX+3 + lda RNDX+4 eor #$04 sta RNDX+4 @@ -41,23 +42,32 @@ rnd_generate: rnd_generate_copy: - // Copy the number to FAC1, order changed on purpose + // Copy the generated number to FAC1, mangle it a little lda RNDX+3 + eor #$62 sta FAC1_mantissa+0 + lda RNDX+1 + eor #$4E sta FAC1_mantissa+1 - lda RNDX+2 - sta FAC1_mantissa+2 + lda RNDX+4 + eor #$97 + sta FAC1_mantissa+2 + + lda RNDX+2 sta FAC1_mantissa+3 - + + // FALLTROUGH + +rnd_generate_finalize: + lda #$00 - sta FACOV sta FAC1_sign lda #$80 + sta FACOV // just to prevent 0 after normalization sta FAC1_exponent - sta RNDX+0 // in case someone tries to use the float directly jmp normal_FAC1 diff --git a/c64/basic/math/rnd_seed_from_FAC1.s b/c64/basic/math/rnd_seed_from_FAC1.s new file mode 100644 index 00000000..0a288ca2 --- /dev/null +++ b/c64/basic/math/rnd_seed_from_FAC1.s @@ -0,0 +1,27 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Initialize random seed using values from FAC1, +// afterwards generate random number in FAC1 +// + +rnd_seed_from_FAC1: + + lda FAC1_mantissa+0 + sta RNDX+4 + + eor FAC1_mantissa+1 + sta RNDX+3 + + eor FAC1_mantissa+2 + sta RNDX+2 + + eor FAC1_mantissa+3 + sta RNDX+1 + + eor FAC1_exponent + sta RNDX+0 + + jmp rnd_generate diff --git a/c64/basic/math/rnd_seed_init.s b/c64/basic/math/rnd_seed_init.s new file mode 100644 index 00000000..56f0a13c --- /dev/null +++ b/c64/basic/math/rnd_seed_init.s @@ -0,0 +1,33 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Initialize random seed, afterwards generate random number in FAC1, +// try to gather as much entropy from different sources as possible +// + +rnd_seed_init: + + eor CIA1_TIMALO // timer used for IRQ generation, use potential entropy from .A + sta RNDX+3 + + txa // .X might contain some entropy + eor VIC_RASTER // lowest 8 bits of current raster line + sta RNDX+1 + + tya // .Y might contain some entropy + eor CIA1_TIMAHI + sta RNDX+4 + + lda TIME+0 // byte from jiffy counter might be useful too + eor SID_RANDOM // not sure if SID set correctly, but it will not hurt +#if CONFIG_MB_MEGA_65 + eor VIC_XPOS // not sure if VIC-IV visible, but it will not hurt +#endif + sta RNDX+2 + + // RNDX+0 will be overwritten by generator + + jmp rnd_generate From 8a8d27b234b8dc28a7f3ccfde863af1cbc900126 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 19 Feb 2020 17:37:15 +0100 Subject: [PATCH 64/66] random generator compatibility fix, updated binaries --- Makefile | 2 +- STATUS.md | 1 + bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes c64/basic/math/e097.interop | 3 +++ c64/basic/math/e097.rnd_FAC1.s | 20 ++++++++++++++++++++ c64/basic/math/e0be.rnd_generate.s | 8 ++++++-- 12 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 c64/basic/math/e097.interop create mode 100644 c64/basic/math/e097.rnd_FAC1.s diff --git a/Makefile b/Makefile index da8927c1..eecfb259 100644 --- a/Makefile +++ b/Makefile @@ -372,7 +372,7 @@ $(TARGET_X16_x): $(SEG_LIST_X16) build/chargen.rom dd if=/dev/zero bs=8192 count=8 of=build/x16_padding_64_KB cat $(DIR_X16)/basic.seg_0 > $(TARGET_X16_x) cat $(DIR_X16)/kernal.seg_0 >> $(TARGET_X16_x) - cat build/chargen.rom >> $(TARGET_X16_x) + cat build/chargen.rom >> $(TARGET_X16_x) cat $(DIR_X16)/basic.seg_1 >> $(TARGET_X16_x) cat $(DIR_X16)/kernal.seg_1 >> $(TARGET_X16_x) rm -f build/x16_padding_* diff --git a/STATUS.md b/STATUS.md index 5ee5f251..10c217d9 100644 --- a/STATUS.md +++ b/STATUS.md @@ -237,6 +237,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BFED` | `exp_FAC1` | NOT DONE | | | `$E043` | `poly1_FAC1` | NOT DONE | | | `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E097` | `rnd_FAC1` | PARTIAL | requires `sgn_FAC1_A` | | `$E09A` | `rnd_A` | DONE | | | `$E0BE` | `rnd_generate` | DONE | | | `$E264` | `cos_FAC1` | NOT DONE | | diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 7db8844e80da01eaa0643a6b6be8327928f7a332..f0f5b1e3c302402e648a49db7f60fbcf2e19139a 100644 GIT binary patch delta 634 zcmYk4PiPZC6vk&a$+k&LYZ9?ZHfbNRjYtJU5vkQ`M9?Y|P$*Q3&^e1BSWqZJBOxMc z(}X!xFS3TlWG&U~hN7fRn}dJ4htfrQDm@t6q6ZHPws`Qc&XS9B`QDp(-)|oCCJ{@- zO1JD>o!$|AG-?0MqWg|vez!o^91*TS_Z)-5rh?d_ok5Wrfu$cqY`sAIDozy%!!c+MJ&ro7h=;G{PkoOOW%Rlt5vZ7~1uA;)Wj#~n zkIoN{E`*4LayRkDA|lYCYR3#GYjz*PYCrK2qPSf=pGna3f`3Fp%7g~G0HTU(iiQk9 z8!&hu=_mPY)P{#=tpcbirHfWz#I(swo9j(=Tpg<3Rfm|1Fmem?MVQZqk8WF_O@*Fm zzQHq@X^!whovt+hag(Rp$=L__Kw+ow=#m$_WLzU#quqW&M}-qvu+t^~Ow)MX z8a|;)Q=bF(><~hy1J`J8u#No%%!?{LD_*c9DTaA=m>0o|2bb{VI~-M|E4j5A<2&Cu z_dDlKrKVD)mt|6PUXi;9DT-6dGxV{F_)-}qrr1^vtG)&JiJ`%yXe9z-I{uJ2uRe^- z&(+_=@x=Zx=mwO}xXe>o%H~Z=eAO3wplOw!Y{RXTo5}TrmTK?Y>DmQ5jTGHwtu7Z@ zqwc|$#P>GZS-vHrk>@FflaW!nR2CmZ{+wey&S$~PN=DbQLjDE*%_`{ZknN7Of+%sD zP1pzYn69VaNf*FSE&|Dh|DH6WSa2Ynr?DC(r$!;w-)S^Bg75mx?lPi$bnx%^Mvs2;zsya16F`|%6eV){=mQB zIQ!aPuPfdy9e@B(02x37qJl(0l?l}lR8#2(2ZpRoB>`Nw5`z04wOvsIQY zmU@`EY7St=Xv6HEsiM|O8}8qMy#Qh>JX%@oUl{P@g|Wqb1z_L$TAFPpo0IqCf=e4= znjhln#_YXs-^U&_*^5{BIa4$PdnW#>xFep#dmVQ?7j_Spy4P{a_v1kJ@mDMCEr->7 zR`;>%Qx5ydXPZrSwQ>olJMNvhMB3pw{<_0Vaa4;xd(6hV|MT;`>}n^|fcn#|ezxp; zy==1sT?D$$Z&Y-YL(x2B$AdMX=>5;$HYyfiv1;h7>SGJyQ|*mD{oTg&!dWw6-Lz&u zK36_c|xiIej5U;<{)gcFnP2u@=7&h*ofRpo?-~zr^?46myBAV((xW9}cG} zTRfV4q8+A_!@^3k0RVn@jc1Ddm~9-%KgB-T;$_SEE_oZ@q2uj7Psk(U#GN1h2TA;N AWdHyG diff --git a/bin/basic_testing.rom b/bin/basic_testing.rom index 04529177655d9a857df36dcc4f2987b70bcef3bd..86d713bdca8a2a0f7e237ec9137b9ea807ce5e97 100644 GIT binary patch delta 758 zcmXw1T}TvB6u$TFpS!xXJ7N1Xse|-`x|Q`{n`KyrZFJW#=phN52to+yF;c;enlepy z;=U-fuxySyYi8?AMD9=d&_h!Y69_>V6uD3kvJjCZXm?yXFCX`ubHDTRok(k>HND@A zx-#T|IfxeK$W^myyg19_3fot$TQ}i-8Sb7!K3YyxKgeJ~N&%rSg@k^JEyA(XhR}?W z45*Rn9V{vOZRCRWk-@ZXZATq4X}7f*Fk%as2I8+s#@67DgG3)UgEUUJavd@*BuUQA zHWiZTj{gx*Y|{qCEsp8@v>eK($6DM=jX!s0Mi;%2d zV_2xZw!g5{0KikWi+C{$cZ=P4hf*MJnE-Ie z^|vSPp`|NB3FOTqc;mDZLvZM=>sJr{IY+jXc>i`CSIARcDpF%pzCfuuvRxj?=8bzDdoHpTAg{+nNj?}B7|GgXPxmg#SVPGDh34m4@ zxZ;9%T$yEH450604Ai1J5*DAhptsizM>m7ytlfj|s-(xh8#Ss#w0pQ-b==DbQ-C*= zprem`yEQo=`IF1ZJG0S@lvNYkHcSj%aXI%X%h@MI6HZUzh)h&ZJE8)tdD`guNUQgq z0Z!j_(&azMmdI`zz&YoG(xF1bv=l4^I4bW4-*6L1v=}-9-SMV`h&I88%}c`AaG24B z`{QBDk`R^RVRlg%#V^0$UCTUAqW(^D(ppLW_Zx$O&*XEpdAL>DCl delta 1086 zcmYjQU1%d!6uvY0?WQs5f0}ICOWAd)jl1bnLzkAYg;4OKyRwT4V&_Q;i$CClm~=@+ zrv&%GiT7m}ErytxW|Fp7F~q_cv(DGsnzjPt5UZVT-mr6SUoPbn@Bq zD$nJ1gTF75o^mdiJJQZd-z^qS7+GmxzUU0;hOSq&5dxMi!{VcDQy1yoN% z(DRyc49rChgakoIcc-4VP65pXF>3f*4eK^;+o0nMjZvNa6_05fh&STqLUw~=_Hpuw zhQHpH2P_9^DssQ!4Z1W3xvq#Ua3|vp75$H-7{DJL&=pYotksX-x6J_l^x)T3#COPP zO@J5xEuvh!O9u&`+dr9qKok`zt%3kLSYB;At36gkz^0uAy!H_LqySd1JM4NI$RI$F z1@N_<(l1+xH}@>3niQqBOBz%WI26&!Op#xiEzaNpU6!m5KqI*%&x2X4?2<1PAcHd9 zy`rQ`8KT>4#Qr<^k@c*!3{TdDG+yToY`SrOgH-DVvfReB#Y4XYIUk2Imkxb!wXQw< zuRpTpVASqAQqiAp%QLo4MBead^B zZHnj}<2&`H>Wy%D?CB9M-+HCAB!|~-udQresx8%;#Xj573!#0`Dcn_(97Iz{szIAW zDZW~#cZcQxPm`gKneh+5NS8(v11~eF*uRyKr}ic)a$+xrVWmDBevOL5lMZtHHqD36 z(KGHL`d9cFmd4YOc;L=W%?t?)i4b{fhpt7i4{kF%BwK@FXqu5nIkuU{q7`P$=-`QJ w9rD>y*a(mPqghUi+j2(SIrzhNzzsv)^pBk5xGB0Y8l|_wgLynguZ@zw0oT0LI{*Lx diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index 98571e4ec991dc3f22561e552bd5b250ca8aabb1..74b9697ba4e6a1af6dd065d0022312010f6cd890 100644 GIT binary patch delta 632 zcmYk3&ubGw6vt;L$);(gHHq3Jo3@W?BT~UoL~6A)qG*)~C{(IJ===eKU_qe@t&|l} zn;*=fdXX3!lU1tS4Mj;C8}J9+gSbdfp$B6tig;MC#e;`+mR_98_c8OnpZA#WL~J59 z=Xc_o%62+02z7Q<46sS(Z(iMS4dHJE_R$p)3T(sG)t)I6Ij#Z(I+)$WUxd91R4k}kX$NUj;JXEHf5MgGEW&!! z7?~Apxky?SD6r?g;BZt^(0~287WlB`%%bW!a|gV#j28H`b@d40Wg-_T$8l&5-Hm!G z2*YRVhq1wl3VK@3QYc$|1t$5gXM9tocb?a-4uohHKM36L6Rdr;FdY_2{w3p^HQ3n~Cu^XVO&YiLgGp3KHn;V~1 zMzz7pHEoc)C?_{@UxfP{WZ#+%;&~lyxMasR-4MZIoh>!|@zVQilQXySp~8CM&Wltz zzfj8gEr*Yzo1m}&yO#L>?Or2sjol6&$$-a6`B?V16?nkmKqse_Vu6zaONa+E;AD%z zY4>Q|&XzLO-Qyx%>y)xo=sfEVH}j|omNYgXov>w6>csppFM*%*FOu<>B&uc4=FY(U YSCS}~YSN}4)JsNNQVIX@g&HbvO|B^42LKOE~e zQt48{1~cXSm=g*y^!DBqWH*moxR16i|8LgCd;Z@Q3$M4QSkbv`QiEV9v+_e zdEfKA=bemC#*5o!>X{-WkCB4?rrb_QL7Y}zrbo--Yh{oaVpAFDd%wa{MjlcVd73(l z@o?%$-b;;e&jdW8uQw(dQJZm1dKtf`fFSBt8uO zIm0^a&;6e&NnOVZx!3sj%b>GEmNV4wqr?L?Y8})gx}Lb0$U|1S3M3u)dpsM)f}uo? zMyiyY*;SmSB)t~6KhD1_q|@oPS~7EMJo`wCBS)%0&KxSvV(J#>_a>*s`Y9(>331vo z+uryW$iaJUvxM-?!dhS>3rj#;Wwj=|f8fnO%)awhYl?ec2Ot0xKnBo&s31{LWkNLs z6%{}s6bV#DimV~YuYyMWl&F#>OVp=orLLz*GBb&G>+G31oWUYnH!~6+syCnAzvY%O zky< z;qrX7 z+2u;S({_e40cWJRZ55~d1P){mf2+*ivsu++H4nQ!ZL?oJc4LFxEMEia47(?)7JMb$-ec zKSz7S+r2{)nl1hbGu(&XNI(8XJ05wCh=y diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 6be4cf2be74e9216b5ac993b1efb67d4cc5ce02c..20ed1acecf21b817d464d6c950d1ce27be97b5ef 100644 GIT binary patch delta 567 zcmXAm&ubGw6oB8%Znm2sHflm!q%wpOtF594QpMC>0vj0o13V?^58_SnV5`Um?36{b z$(9_%LmI`-s8QQ!^5|9u3sz%;@NsL?WXKgPooS<5F<;?O~a)FbDSM)yD9%?1XyPg0tynhq zwE`Y)V6-&W$zh}$ZSP)!zI6=4@HBPnQzCz|FUi9VKucFTIZ=Dy{OCD->tjJ`Ak^|$ zhyDSY`sT?YM1MPN@Ao{^0NJjcrfmNaC-*t>et)OwviG6@2mk}f04g8_Bn*m-a7Y!@ zr2x1P76z7uBdfx4E1)7bMvA1$5*|=g(V-Vnve*%eiPxsPmFyzELwKBJ!m}(Lo?~Ws zo~6Pu_DKA%a34elcMH+%5h;*8FI`1W_Lg*Uq_UoeN=VzOgxGX~g`#x1Rv4vkO3~F= QJR6XoqDwEf<;%za1A$Q3^Z)<= delta 112 zcmZp0XmFS?eewn7Aap!Yz=}6Pq2iHG?NWuMk9__wpIpIIK9N<5t=W_R)}n;Tg3L;j z4Vmp3*H12FHj|9nwSZxxt;dOtwyky;J;$%gZC5+~qkFi)u F0{{eEEB^oh diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index cee5e14c90dda0e2a4fe67f2566f3bfc98b2ecc4..6628e7a2244a5bd8b141b8617e58ca36280a4ee7 100644 GIT binary patch delta 516 zcmY+BPiPZC6vijJX;BmsFja~K1}QmM&|Cx?spb-Kagg5Z&HQOaZ;H1RNe;dunB8p2 zp?VP3)!8~iVM`CSsVggD$a--RMDXMWq#}ZQ@aAEBOE2vl<~`oL@Au7{X_wn&b2Ue& z-vlI7+1-B7c2)NFJNq+QNgZpAcM5vJD0JOP-qE(8!*wkWIyba;VDPS%hVFT8+#Wz3 zkFP-kOLbV_`jmbe76pNuq78ST##){rPl-ZzCB4T*#>&vX6e(y51(t+_l0`O}=PhNLQ)QP%3G2*nYDDWq35wy3^;8n(+02N3 z+u;+j$~GOI3l3$+T$R0cppV_G@lud|3_C*ydo+vqb8(Jt$uL7d?UkMoW!PeCQ58K< zYmTvu$-R8(UbhL-+&R>{SCj2Bsw_E7(hCSfgKT1O#7~>Q zwuut{h|{7BraxvL7X%w@vOH@m%NOlgI^l6MeouGvlHKQ5aMW9`KC&+k((s-BJ$9Ne zmY64d^UCT8UWaa_0Y+s3^vWW1Dm8e7|JNH=pG`j4CI=Q<+p+WPgQ%|5>b+Cx=c$>^ ILArGEKa+s&t^fc4 delta 88 zcmZp0XmFS?ee(jY8pg>Nm;)!LFm;PBU|3|Uu!iX*!v(Gr5SmFM!6IQY8}mZRs9g*w ez-Q_1MY29eS0+rJ$dxo%iDfaP`Q~FRR?+}2Hyi2z diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index fc119cd3b0f04d34d984672bd69734fe51d519ec..d000620b6d21f619c20ddebea254de5da9761d50 100644 GIT binary patch delta 547 zcmXAm(Q8t16vxl+cdvI>iDsp2BNjho*w$7QL9EC%0^tfj`U84W=Z3u%J*|ih({h?e?v33>@)sSq@Xf<+HKw0@g!=X}oRdpK|s^ND%usfSG0 z+h9xdcCno(OZ4?u`m?u=PU%Y0Z~9aIba{*?LsgdKW@wz5JQaG&Qal}!S$dYI?(DFr z7~f(G0!3Mjn-k_awpaqTR7$YBEJF1Lxmgf>l{71sL}&VBWV7x2CDExqf55i+LslP< zVR3~*e4BKx`>jeR^)5MCU)>_c%kpuuvCX|A;_q`0+Y-xahuCw3?IFQx^nSPKDR^zU zFjJf^0r_;GYUJHseA05h=(utI4AuIp=T|O}%bYB|p^v!sL@Png@eGjR{u|GYv~|m? zHAW6Jrd3Ms~!2;>Hq%} B(Gmav delta 98 zcmZp0XmFS?eewn7Aap!Yz-n?fQ_DnFDYj-${#%O@CJQnvO*UkqHrlq@WwhER_(UyRBp(P|rQ_Fyx_KFGR;Z%ck2y63 z{4YAz1dD5VQBXKq-2^kWQWN}f4f+I#i-;sKC*zbc;Bz+Sfe3Hcel7jU`4kY(MlsCR zcmdR&z7R15(%&d^mNo!z6vSRbcXWW^X3f}BZRDl?1sz&9ZoxP`ntEP{*cQdGmmZ35 zITi)#lmSatXxC6dH9*yB^j5_d+>Pak(}V`4dH^h_sTb-_^`PMiKfLZ*ep2htPiXx- z3v>4MJg=SSnb4Q}_^|eW$-9 zU1aYtYnd)2A2j1jm1*gH`SHX`;-ed(tgPd-?}I-~ZP;zTOM)M}n@hxh#cjDuLUPn? zzvDhyA_4T(GCj2160z+uV_qfwJ9D_M?ZLS&@l`XOoV&tz>4)Y!1k+4(mOh=`PSwPI z3);DYF^y!u5bYX0pdYTAY2EP@#;|vuOBAlb(+l;c*Tc&d_}Bv1HWf#14FJ@aL!MdW z)S@rO2H;JGhO$)Fw~OEBXifitF6j>Xdu~}Mr%U;uAoQe6WB@L_LqiA3zhuy^GG*#sak5M|YEROc*(aRrswnurwcQ^>#j?-mTUYRee;$i= z@GtOaf6UyH2g1A0u&dy|nBU6u-t1OBLDtl8BfwyFVLHzGsFzvj4K~p-D8bGObmdTU zC2CUp`h9BOwJ|=Ww7W7astJ0zvaMk#9&1In6dVyosAJ`Gp=Y|dk}0kTz4m_r%Cpj~ delta 862 zcmYjPZ)j6j6u<91Ev^3=irTQw_FAn4?Pe;2*0@MFsdjQ<16$N$=|y1_W_7L3Zmy+) zt|Krg2}h~3h#^bzUIO;z<)LYl7g|9>pR^i^pZub|Nvp^{WK3~mu(zAm54&H^J?Ea^ z@BGd=*X=HKyGvv3LFf$chml~F5Q5vmM)AUCSPXWFmJE%dRzZbSBggIGIEmZ~7m0Y`%J}KMmb_wo!_Ko_c7a`F-?Bc|&&Cti5|`Lz z_8q&z=2P>=0Q;UrHMkjn=d*3mA4I0s*HFq;1UM8WgO_Gb^ts2-1J!|bs4d5^!ItJ~HVSZ7Zo;fF)9Tj+hx?<%}ps^+biur7T< z{akQ)-3W1Z=X3;(CU|>ZiA;x!#cEfZ2wfdbg?=10)*|I5;sZLS5T>mp$h-!Jmp&3J z!!nNGo7(bb9_?!x#oSOH;&ypPFr}^;w1)j{L;ep1)PcB zL89r%cHa?-<`n7E;Y+3JWQP(#|H}@Pfi9C;q6oQzWj zkjGJ$Mj~FcUS;2Kz6c5@{S+rHE&%Q;S1RZ)xsl*t=mR+~|2#RQ4ysi54E-V1tW5!X zE&TONanT#`cn)u$;c{bP(yzd0FYG>B!#c{};Ge{i;;(9%Y7~1UxHNTxd-~?-dOe=*|AT;USGtE0S+k#L^ z`9Arf(8pZhX6s>+_1hN=yf24a4N{TwOPZ_Aqq(9zoC%t9U1Dbv#&bJM+k=4}bB6yx^?*4}j8|OaK4? diff --git a/c64/basic/math/e097.interop b/c64/basic/math/e097.interop new file mode 100644 index 00000000..6b2f206f --- /dev/null +++ b/c64/basic/math/e097.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, referenced by ACME SDK, see here: + +- https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True diff --git a/c64/basic/math/e097.rnd_FAC1.s b/c64/basic/math/e097.rnd_FAC1.s new file mode 100644 index 00000000..0091fe7f --- /dev/null +++ b/c64/basic/math/e097.rnd_FAC1.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Random number generator routine +// +// Input: +// - FAC1 (0 - reinitialize the seed with random value, negative - create seed from FAC1) +// +// Output: +// - FAC1 +// + +rnd_FAC1: + + jsr sgn_FAC1_A + + // FALLTROUGH to rnd_A + diff --git a/c64/basic/math/e0be.rnd_generate.s b/c64/basic/math/e0be.rnd_generate.s index d315cc1a..f33e2921 100644 --- a/c64/basic/math/e0be.rnd_generate.s +++ b/c64/basic/math/e0be.rnd_generate.s @@ -38,6 +38,8 @@ rnd_generate: eor #$04 sta RNDX+4 + sec // make sure Carry is always set, for adc + // FALLTROUGH rnd_generate_copy: @@ -45,7 +47,7 @@ rnd_generate_copy: // Copy the generated number to FAC1, mangle it a little lda RNDX+3 - eor #$62 + adc #$C6 sta FAC1_mantissa+0 lda RNDX+1 @@ -53,10 +55,12 @@ rnd_generate_copy: sta FAC1_mantissa+1 lda RNDX+4 - eor #$97 + eor #$62 sta FAC1_mantissa+2 lda RNDX+2 + bit RNDX+2 + rol sta FAC1_mantissa+3 // FALLTROUGH From c75375f9fa48557749339dab2e25b650345ee20b Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 21 Feb 2020 18:43:18 +0100 Subject: [PATCH 65/66] added examples to many routines, small change to avoid similarity --- c64/basic/,stubs_math/aabc.interop | 3 ++- c64/basic/,stubs_math/b1aa.interop | 3 ++- c64/basic/,stubs_math/b391.interop | 3 ++- c64/basic/,stubs_math/b3a2.interop | 4 +++- c64/basic/,stubs_math/b7b5.interop | 3 ++- c64/basic/,stubs_math/b7f7.interop | 3 ++- c64/basic/,stubs_math/b849.interop | 3 ++- c64/basic/,stubs_math/b9ea.interop | 4 +++- c64/basic/,stubs_math/bae2.interop | 3 ++- c64/basic/,stubs_math/bafe.interop | 4 +++- c64/basic/,stubs_math/bc2b.interop | 3 ++- c64/basic/,stubs_math/bc39.interop | 3 ++- c64/basic/,stubs_math/bc3c.interop | 3 ++- c64/basic/,stubs_math/bc58.interop | 3 ++- c64/basic/,stubs_math/bc5b.interop | 3 ++- c64/basic/,stubs_math/bc9b.interop | 3 ++- c64/basic/,stubs_math/bccc.interop | 3 ++- c64/basic/,stubs_math/bf71.interop | 3 ++- c64/basic/,stubs_math/bf74.interop | 3 ++- c64/basic/,stubs_math/bf78.interop | 3 ++- c64/basic/,stubs_math/bf7b.interop | 3 ++- c64/basic/,stubs_math/bfed.interop | 3 ++- c64/basic/,stubs_math/e264.interop | 3 ++- c64/basic/,stubs_math/e26b.interop | 3 ++- c64/basic/,stubs_math/e2b4.interop | 3 ++- c64/basic/math/b853.interop | 3 ++- c64/basic/math/b86a.interop | 3 ++- c64/basic/math/ba28.interop | 3 ++- c64/basic/math/ba2b.interop | 3 ++- c64/basic/math/ba8c.interop | 3 ++- c64/basic/math/bb0f.interop | 3 ++- c64/basic/math/bbd4.interop | 3 ++- c64/basic/math/bc0c.interop | 3 ++- c64/basic/math/bc0f.interop | 3 ++- c64/basic/math/bfb4.interop | 3 ++- c64/basic/math/e09a.interop | 4 ++-- c64/basic/math/e0be.interop | 4 ++-- c64/kernal/tape/tape_normal_get_data_1.s | 2 +- 38 files changed, 78 insertions(+), 40 deletions(-) diff --git a/c64/basic/,stubs_math/aabc.interop b/c64/basic/,stubs_math/aabc.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/aabc.interop +++ b/c64/basic/,stubs_math/aabc.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b1aa.interop b/c64/basic/,stubs_math/b1aa.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/b1aa.interop +++ b/c64/basic/,stubs_math/b1aa.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b391.interop b/c64/basic/,stubs_math/b391.interop index 0d18777c..62124f9a 100644 --- a/c64/basic/,stubs_math/b391.interop +++ b/c64/basic/,stubs_math/b391.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example codoe utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b3a2.interop b/c64/basic/,stubs_math/b3a2.interop index 0d18777c..8b4c9dc2 100644 --- a/c64/basic/,stubs_math/b3a2.interop +++ b/c64/basic/,stubs_math/b3a2.interop @@ -1,3 +1,5 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 + diff --git a/c64/basic/,stubs_math/b7b5.interop b/c64/basic/,stubs_math/b7b5.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/b7b5.interop +++ b/c64/basic/,stubs_math/b7b5.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b7f7.interop b/c64/basic/,stubs_math/b7f7.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/b7f7.interop +++ b/c64/basic/,stubs_math/b7f7.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b849.interop b/c64/basic/,stubs_math/b849.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/b849.interop +++ b/c64/basic/,stubs_math/b849.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/b9ea.interop b/c64/basic/,stubs_math/b9ea.interop index 0d18777c..8b4c9dc2 100644 --- a/c64/basic/,stubs_math/b9ea.interop +++ b/c64/basic/,stubs_math/b9ea.interop @@ -1,3 +1,5 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 + diff --git a/c64/basic/,stubs_math/bae2.interop b/c64/basic/,stubs_math/bae2.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bae2.interop +++ b/c64/basic/,stubs_math/bae2.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bafe.interop b/c64/basic/,stubs_math/bafe.interop index 0d18777c..8b4c9dc2 100644 --- a/c64/basic/,stubs_math/bafe.interop +++ b/c64/basic/,stubs_math/bafe.interop @@ -1,3 +1,5 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 + diff --git a/c64/basic/,stubs_math/bc2b.interop b/c64/basic/,stubs_math/bc2b.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc2b.interop +++ b/c64/basic/,stubs_math/bc2b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bc39.interop b/c64/basic/,stubs_math/bc39.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc39.interop +++ b/c64/basic/,stubs_math/bc39.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bc3c.interop b/c64/basic/,stubs_math/bc3c.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc3c.interop +++ b/c64/basic/,stubs_math/bc3c.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bc58.interop b/c64/basic/,stubs_math/bc58.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc58.interop +++ b/c64/basic/,stubs_math/bc58.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bc5b.interop b/c64/basic/,stubs_math/bc5b.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc5b.interop +++ b/c64/basic/,stubs_math/bc5b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bc9b.interop b/c64/basic/,stubs_math/bc9b.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bc9b.interop +++ b/c64/basic/,stubs_math/bc9b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bccc.interop b/c64/basic/,stubs_math/bccc.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bccc.interop +++ b/c64/basic/,stubs_math/bccc.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bf71.interop b/c64/basic/,stubs_math/bf71.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bf71.interop +++ b/c64/basic/,stubs_math/bf71.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bf74.interop b/c64/basic/,stubs_math/bf74.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bf74.interop +++ b/c64/basic/,stubs_math/bf74.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bf78.interop b/c64/basic/,stubs_math/bf78.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bf78.interop +++ b/c64/basic/,stubs_math/bf78.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bf7b.interop b/c64/basic/,stubs_math/bf7b.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bf7b.interop +++ b/c64/basic/,stubs_math/bf7b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/bfed.interop b/c64/basic/,stubs_math/bfed.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/,stubs_math/bfed.interop +++ b/c64/basic/,stubs_math/bfed.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/,stubs_math/e264.interop b/c64/basic/,stubs_math/e264.interop index 0d18777c..8e0ca383 100644 --- a/c64/basic/,stubs_math/e264.interop +++ b/c64/basic/,stubs_math/e264.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Usage example: +- https://www.lemon64.com/forum/viewtopic.php?t=10492 diff --git a/c64/basic/,stubs_math/e26b.interop b/c64/basic/,stubs_math/e26b.interop index 0d18777c..8e0ca383 100644 --- a/c64/basic/,stubs_math/e26b.interop +++ b/c64/basic/,stubs_math/e26b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Usage example: +- https://www.lemon64.com/forum/viewtopic.php?t=10492 diff --git a/c64/basic/,stubs_math/e2b4.interop b/c64/basic/,stubs_math/e2b4.interop index 0d18777c..8e0ca383 100644 --- a/c64/basic/,stubs_math/e2b4.interop +++ b/c64/basic/,stubs_math/e2b4.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Usage example: +- https://www.lemon64.com/forum/viewtopic.php?t=10492 diff --git a/c64/basic/math/b853.interop b/c64/basic/math/b853.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/math/b853.interop +++ b/c64/basic/math/b853.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/math/b86a.interop b/c64/basic/math/b86a.interop index 0d18777c..1b7d0105 100644 --- a/c64/basic/math/b86a.interop +++ b/c64/basic/math/b86a.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- http://cbm-hackers.2304266.n4.nabble.com/unsigned-to-float-td4668532.html#a4668556 diff --git a/c64/basic/math/ba28.interop b/c64/basic/math/ba28.interop index 0d18777c..0a30d506 100644 --- a/c64/basic/math/ba28.interop +++ b/c64/basic/math/ba28.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://www.lemon64.com/forum/viewtopic.php?t=42934 diff --git a/c64/basic/math/ba2b.interop b/c64/basic/math/ba2b.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/math/ba2b.interop +++ b/c64/basic/math/ba2b.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/math/ba8c.interop b/c64/basic/math/ba8c.interop index 0d18777c..0a30d506 100644 --- a/c64/basic/math/ba8c.interop +++ b/c64/basic/math/ba8c.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://www.lemon64.com/forum/viewtopic.php?t=42934 diff --git a/c64/basic/math/bb0f.interop b/c64/basic/math/bb0f.interop index 0d18777c..50ba7802 100644 --- a/c64/basic/math/bb0f.interop +++ b/c64/basic/math/bb0f.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://codebase64.org/doku.php?id=base:mandelbrot diff --git a/c64/basic/math/bbd4.interop b/c64/basic/math/bbd4.interop index 0d18777c..50ba7802 100644 --- a/c64/basic/math/bbd4.interop +++ b/c64/basic/math/bbd4.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://codebase64.org/doku.php?id=base:mandelbrot diff --git a/c64/basic/math/bc0c.interop b/c64/basic/math/bc0c.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/math/bc0c.interop +++ b/c64/basic/math/bc0c.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/math/bc0f.interop b/c64/basic/math/bc0f.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/math/bc0f.interop +++ b/c64/basic/math/bc0f.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/math/bfb4.interop b/c64/basic/math/bfb4.interop index 0d18777c..c4ad4680 100644 --- a/c64/basic/math/bfb4.interop +++ b/c64/basic/math/bfb4.interop @@ -1,3 +1,4 @@ This is an important floating point math routine, documented in many places. -XXX - try to find real-life example +Example code utilizing this routine: +- https://github.com/irmen/prog8/blob/master/compiler/res/prog8lib/c64flt.p8 diff --git a/c64/basic/math/e09a.interop b/c64/basic/math/e09a.interop index 5c452b05..c876324b 100644 --- a/c64/basic/math/e09a.interop +++ b/c64/basic/math/e09a.interop @@ -1,5 +1,5 @@ This is an important floating point math routine, see: - - https://www.atarimagazines.com/compute/issue72/random_numbers.php -XXX - try to find real-life example +Example code utilizing the routine: +- https://stackoverflow.com/questions/44937759/getting-random-number-from-6502-assembler/44937995 diff --git a/c64/basic/math/e0be.interop b/c64/basic/math/e0be.interop index 5c452b05..c42eaa6a 100644 --- a/c64/basic/math/e0be.interop +++ b/c64/basic/math/e0be.interop @@ -1,5 +1,5 @@ This is an important floating point math routine, see: - - https://www.atarimagazines.com/compute/issue72/random_numbers.php -XXX - try to find real-life example +Example coode utilizing this routine: +- https://www.lemon64.com/forum/viewtopic.php?t=56934&sid=387926a3f1d6373a384c0f7328b00c30 diff --git a/c64/kernal/tape/tape_normal_get_data_1.s b/c64/kernal/tape/tape_normal_get_data_1.s index 8b07ccb7..fd1242c6 100644 --- a/c64/kernal/tape/tape_normal_get_data_1.s +++ b/c64/kernal/tape/tape_normal_get_data_1.s @@ -22,8 +22,8 @@ tape_normal_get_data_1: lda #$00 sta RIPRTY #if !CONFIG_TAPE_NO_ERROR_CORRECTION - sta PTR1 sta PTR2 + sta PTR1 #endif // FALLTROUGH From faf4245da86e5f28e309faa19c53b53c237f9d48 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 23 Feb 2020 11:17:32 +0100 Subject: [PATCH 66/66] explained similarities >3, updated binaries --- LICENSE | 2 +- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_testing.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_testing.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes bin/mega65.rom | Bin 131072 -> 131072 bytes strings/00000080 | 3 +++ strings/000020 | 3 +++ strings/00202BBC | 3 +++ strings/00602017 | 3 +++ strings/0060A5 | 3 +++ strings/008D8D02A0 | 3 +++ strings/00B17AD0 | 3 +++ strings/00DC60AD | 3 +++ strings/012CA900 | 3 +++ strings/04B12285 | 3 +++ strings/04B122856588B122856488B122856388B122 | 3 +++ strings/04B122856D88B122856C88B122856B88B122 | 3 +++ strings/09808562 | 3 +++ strings/122067F8 | 3 +++ strings/18690285 | 3 +++ strings/2285618470 | 3 +++ strings/228569A56160 | 3 +++ strings/22856D88B122856C88B122856B88B122 | 3 +++ strings/22D008A5D449 | 3 +++ strings/2CA90085 | 3 +++ strings/2CA9042CA9 | 3 +++ strings/3504F334 | 3 +++ strings/38E90285 | 3 +++ strings/490FDAA2 | 3 +++ strings/4C0CED4C | 3 +++ strings/608100000000 | 3 +++ strings/61D0034C | 3 +++ strings/61F006A56649FF8566608138AA3B29 | 8 ++++++++ strings/62666366646665667060 | 3 +++ strings/63856BA5 | 3 +++ strings/64856CA5 | 3 +++ strings/65856DA5 | 3 +++ strings/66456E85 | 3 +++ strings/6649FF8566 | 3 +++ strings/66626663666466656670 | 3 +++ strings/6662666366646665667060 | 3 +++ strings/6A85624C | 3 +++ strings/6AE56285 | 3 +++ strings/6B8563A5 | 3 +++ strings/6B8563A562 | 3 +++ strings/6C8564A5 | 3 +++ strings/6CE56485 | 3 +++ strings/6D8565A5 | 3 +++ strings/6D8565A564 | 3 +++ strings/702665266426632662 | 3 +++ .../803504F334813504F334808000000080317217F8 | 3 +++ strings/8100000000 | 3 +++ strings/81490FDAA283490FDAA27F00000000 | 3 +++ strings/82490FDA | 3 +++ strings/83490FDAA2 | 3 +++ strings/8420000000 | 3 +++ strings/8561A56585 | 3 +++ strings/8562856385648565 | 3 +++ strings/8562B003 | 3 +++ strings/8563A562 | 3 +++ strings/8566A561 | 3 +++ strings/867060 | 3 +++ strings/88B122 | 3 +++ strings/88B12285 | 3 +++ strings/8D00DCAD01DC | 3 +++ strings/9080000000 | 3 +++ strings/A0008470 | 3 +++ strings/A5619122 | 3 +++ strings/A56649FF | 3 +++ strings/A56649FF8566 | 3 +++ strings/A56AE56285 | 3 +++ strings/A56DE56585 | 3 +++ strings/A56E8566 | 3 +++ strings/A5A745AB85AB | 3 +++ strings/A5C485C2 | 3 +++ strings/A6D8F005 | 3 +++ ...2CA9032CA9042CA9052CA9062CA9072CA9082CA909 | 3 +++ strings/A9802CA9 | 3 +++ strings/B12285 | 4 ++++ strings/B1228565 | 3 +++ strings/BA200CED | 3 +++ strings/BAC902D0 | 3 +++ strings/D885F46020 | 3 +++ strings/E69FE69F | 4 ++++ strings/F38810F5 | 3 +++ strings/F7B0034C | 3 +++ strings/F7C884C8A0 | 3 +++ 90 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 strings/00000080 create mode 100644 strings/000020 create mode 100644 strings/00202BBC create mode 100644 strings/00602017 create mode 100644 strings/0060A5 create mode 100644 strings/008D8D02A0 create mode 100644 strings/00B17AD0 create mode 100644 strings/00DC60AD create mode 100644 strings/012CA900 create mode 100644 strings/04B12285 create mode 100644 strings/04B122856588B122856488B122856388B122 create mode 100644 strings/04B122856D88B122856C88B122856B88B122 create mode 100644 strings/09808562 create mode 100644 strings/122067F8 create mode 100644 strings/18690285 create mode 100644 strings/2285618470 create mode 100644 strings/228569A56160 create mode 100644 strings/22856D88B122856C88B122856B88B122 create mode 100644 strings/22D008A5D449 create mode 100644 strings/2CA90085 create mode 100644 strings/2CA9042CA9 create mode 100644 strings/3504F334 create mode 100644 strings/38E90285 create mode 100644 strings/490FDAA2 create mode 100644 strings/4C0CED4C create mode 100644 strings/608100000000 create mode 100644 strings/61D0034C create mode 100644 strings/61F006A56649FF8566608138AA3B29 create mode 100644 strings/62666366646665667060 create mode 100644 strings/63856BA5 create mode 100644 strings/64856CA5 create mode 100644 strings/65856DA5 create mode 100644 strings/66456E85 create mode 100644 strings/6649FF8566 create mode 100644 strings/66626663666466656670 create mode 100644 strings/6662666366646665667060 create mode 100644 strings/6A85624C create mode 100644 strings/6AE56285 create mode 100644 strings/6B8563A5 create mode 100644 strings/6B8563A562 create mode 100644 strings/6C8564A5 create mode 100644 strings/6CE56485 create mode 100644 strings/6D8565A5 create mode 100644 strings/6D8565A564 create mode 100644 strings/702665266426632662 create mode 100644 strings/803504F334813504F334808000000080317217F8 create mode 100644 strings/8100000000 create mode 100644 strings/81490FDAA283490FDAA27F00000000 create mode 100644 strings/82490FDA create mode 100644 strings/83490FDAA2 create mode 100644 strings/8420000000 create mode 100644 strings/8561A56585 create mode 100644 strings/8562856385648565 create mode 100644 strings/8562B003 create mode 100644 strings/8563A562 create mode 100644 strings/8566A561 create mode 100644 strings/867060 create mode 100644 strings/88B122 create mode 100644 strings/88B12285 create mode 100644 strings/8D00DCAD01DC create mode 100644 strings/9080000000 create mode 100644 strings/A0008470 create mode 100644 strings/A5619122 create mode 100644 strings/A56649FF create mode 100644 strings/A56649FF8566 create mode 100644 strings/A56AE56285 create mode 100644 strings/A56DE56585 create mode 100644 strings/A56E8566 create mode 100644 strings/A5A745AB85AB create mode 100644 strings/A5C485C2 create mode 100644 strings/A6D8F005 create mode 100644 strings/A9012CA9022CA9032CA9042CA9052CA9062CA9072CA9082CA909 create mode 100644 strings/A9802CA9 create mode 100644 strings/B12285 create mode 100644 strings/B1228565 create mode 100644 strings/BA200CED create mode 100644 strings/BAC902D0 create mode 100644 strings/D885F46020 create mode 100644 strings/E69FE69F create mode 100644 strings/F38810F5 create mode 100644 strings/F7B0034C create mode 100644 strings/F7C884C8A0 diff --git a/LICENSE b/LICENSE index e7be5d84..310d50d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The following copyright notices apply to the entirety of this package, -including each source file, unless otherwise noted in each file. +including each source file, unless otherwise noted in each file or directory. Copyright Paul Gardner-Stephen, 2019. Copyright Roman Standzikowski (FeralChil64), 2019-2020. diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index f0f5b1e3c302402e648a49db7f60fbcf2e19139a..7828da6c6598c21531abe94742894e9f0a97f4ae 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$PJUL!|Apj(-1jYaW delta 14 VcmZp0XmHpNE6-$TIXPZ_Apj)A1j_&b diff --git a/bin/basic_testing.rom b/bin/basic_testing.rom index 86d713bdca8a2a0f7e237ec9137b9ea807ce5e97..6d2c34fe09598e9bc988319b0afff43266036e27 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$PJUL!|Apj(-1jYaW delta 14 VcmZp0XmHpNE6-$TIXPZ_Apj)A1j_&b diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index 74b9697ba4e6a1af6dd065d0022312010f6cd890..1fed28bdd740aa62d4399cbaa3a9c2e8807f1685 100644 GIT binary patch delta 14 VcmZp0XmHpNE6-$PJUL!|Apj(-1jYaW delta 14 VcmZp0XmHpNE6-$TIXPZ_Apj)A1j_&b diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 20ed1acecf21b817d464d6c950d1ce27be97b5ef..0df4af2e1bc8d88ee7bedab16967ce4ab48278c2 100644 GIT binary patch delta 24 gcmZp0XmHqYgoVk-c=IuqUBb-sTjyz>% delta 24 gcmZp0XmHqYgoVk_a`Q2kUBb-sTIX+WmZ)V10ChD9MgRZ+ diff --git a/bin/kernal_testing.rom b/bin/kernal_testing.rom index 6628e7a2244a5bd8b141b8617e58ca36280a4ee7..6684bfdb668ccd6d7a825d4d49542cb9a4d7b4ef 100644 GIT binary patch delta 15 WcmZp0XmHqYgoVk-c=It9D`@~Ny#+D= delta 15 WcmZp0XmHqYgoVk_a`Q13D`@~N+66ZN diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index d000620b6d21f619c20ddebea254de5da9761d50..df0183097fe0676582fd35bfca2d860877b5668a 100644 GIT binary patch delta 24 gcmZp0XmHqYgoVk-c=IuqUBb-sTjyz>% delta 24 gcmZp0XmHqYgoVk_a`Q2kUBb-sTIX+WmZ)V10ChD9MgRZ+ diff --git a/bin/mega65.rom b/bin/mega65.rom index c637aa65f8f2afb9a658a38f82158016f7071acf..ece821ce4d6b6fd08036a79fdf69647a6fa1ba55 100644 GIT binary patch delta 38 tcmZo@;Am*z*kBRMJim3`X6sm`Bqk%{&GGwFRe^N#u_xP)Jz=zx1^^kE4)*{6 delta 38 tcmZo@;Am*z*kBRMJg;^BX6sm`Bql@4&GGwFRe^N#u_xP)Jz=zx1^^l%4*>uG diff --git a/strings/00000080 b/strings/00000080 new file mode 100644 index 00000000..74f02616 --- /dev/null +++ b/strings/00000080 @@ -0,0 +1,3 @@ +some 0's + $80 + +Not creative - not copyrightable. diff --git a/strings/000020 b/strings/000020 new file mode 100644 index 00000000..daa82e1f --- /dev/null +++ b/strings/000020 @@ -0,0 +1,3 @@ +some 0's + $20 + +Not creative - not copyrightable. diff --git a/strings/00202BBC b/strings/00202BBC new file mode 100644 index 00000000..179489eb --- /dev/null +++ b/strings/00202BBC @@ -0,0 +1,3 @@ +$00 + JSR $BC2B + +Instruction (call of well-known subroutine) + some part. Trivial, not copyrightable. diff --git a/strings/00602017 b/strings/00602017 new file mode 100644 index 00000000..6dcd48ba --- /dev/null +++ b/strings/00602017 @@ -0,0 +1,3 @@ +$00 + RTS + JSR $xx17 + +Instruction and some parts. Trivial - not copyrightable. diff --git a/strings/0060A5 b/strings/0060A5 new file mode 100644 index 00000000..5acfc780 --- /dev/null +++ b/strings/0060A5 @@ -0,0 +1,3 @@ +$00 + RTS + LDA (zeropage address does not match) + +Instruction + some parts. Trivial - not copyrightable. diff --git a/strings/008D8D02A0 b/strings/008D8D02A0 new file mode 100644 index 00000000..9b7ba485 --- /dev/null +++ b/strings/008D8D02A0 @@ -0,0 +1,3 @@ +$00 + STA $028D + LDY (immediate value does not match) + +Instruction + some parts. Trivial - not copyrightable. diff --git a/strings/00B17AD0 b/strings/00B17AD0 new file mode 100644 index 00000000..8d207f6a --- /dev/null +++ b/strings/00B17AD0 @@ -0,0 +1,3 @@ +$00 + LDA ($7A),Y + BNE (offset does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/00DC60AD b/strings/00DC60AD new file mode 100644 index 00000000..d5c28289 --- /dev/null +++ b/strings/00DC60AD @@ -0,0 +1,3 @@ +$DC00 + RTS + LDA (address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/012CA900 b/strings/012CA900 new file mode 100644 index 00000000..900f8140 --- /dev/null +++ b/strings/012CA900 @@ -0,0 +1,3 @@ +$01 + $2C (BIT) + LDA #$00 + +Instruction + part of the common BIT trick to save some memory. Trivial - not copyrightable. diff --git a/strings/04B12285 b/strings/04B12285 new file mode 100644 index 00000000..9661fafd --- /dev/null +++ b/strings/04B12285 @@ -0,0 +1,3 @@ +$04 + LDA ($22),Y + STA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/04B122856588B122856488B122856388B122 b/strings/04B122856588B122856488B122856388B122 new file mode 100644 index 00000000..b00b8058 --- /dev/null +++ b/strings/04B122856588B122856488B122856388B122 @@ -0,0 +1,3 @@ +$04 + LDA ($22),Y + STA $65 + DEY + LDA ($22),Y + STA $64 + DEY + LDA ($22),Y + STA $64 + DEY + LDA ($22),Y + +Unrolled loop to copy values from memory location to a fixed zeropage location. Trivial - not copyrightable. diff --git a/strings/04B122856D88B122856C88B122856B88B122 b/strings/04B122856D88B122856C88B122856B88B122 new file mode 100644 index 00000000..7bd466c8 --- /dev/null +++ b/strings/04B122856D88B122856C88B122856B88B122 @@ -0,0 +1,3 @@ +$04 + LDA ($22),Y + STA $6D + DEY + LDA ($22),Y + STA $6C + DEY + LDA ($22),Y + STA $6B + DEY + LDA ($22),Y + +Unrolled loop to copy values from memory location to a fixed zeropage location. Trivial - not copyrightable. diff --git a/strings/09808562 b/strings/09808562 new file mode 100644 index 00000000..e220392b --- /dev/null +++ b/strings/09808562 @@ -0,0 +1,3 @@ +ORA #$80 + STA $62 + +Store .A with highest bit enforced in a memoryy location (small piece of code manipulating floating point value) - trivial, not copyrightable. diff --git a/strings/122067F8 b/strings/122067F8 new file mode 100644 index 00000000..e7563bbe --- /dev/null +++ b/strings/122067F8 @@ -0,0 +1,3 @@ +$12 + JSR $F867 + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/18690285 b/strings/18690285 new file mode 100644 index 00000000..e8e426eb --- /dev/null +++ b/strings/18690285 @@ -0,0 +1,3 @@ +CLC + ADC #$02 + STA (address does not match) + +Adding 2 to .A regardless of Carry flag state, storing result in memoryy (address does not match) - trivial, not copyrightable. diff --git a/strings/2285618470 b/strings/2285618470 new file mode 100644 index 00000000..b587160f --- /dev/null +++ b/strings/2285618470 @@ -0,0 +1,3 @@ +$22 + STA $61 + STY $70 + +Small piece of floating point values manipulation code. Trivial - not copyrightable. diff --git a/strings/228569A56160 b/strings/228569A56160 new file mode 100644 index 00000000..97d81fe6 --- /dev/null +++ b/strings/228569A56160 @@ -0,0 +1,3 @@ +$22 + STA $69 + LDA $61 + RTS + +Small part of code manipulating bytes of a well-known floating point pseudo-register. Trivial - not copyrightable. diff --git a/strings/22856D88B122856C88B122856B88B122 b/strings/22856D88B122856C88B122856B88B122 new file mode 100644 index 00000000..8421e963 --- /dev/null +++ b/strings/22856D88B122856C88B122856B88B122 @@ -0,0 +1,3 @@ +$22 + STA $6D + DEY + LDA ($22),Y + STA $6C + DEY + LDA ($22),Y + STA $6B + DEY + LDA ($22),Y + +Part of unrolled loop to copy value from memor location to a floating point accumulator. Trivial - not copyrightable. diff --git a/strings/22D008A5D449 b/strings/22D008A5D449 new file mode 100644 index 00000000..92a47fb7 --- /dev/null +++ b/strings/22D008A5D449 @@ -0,0 +1,3 @@ +$22 + BNE (offset matches) + LDA $D4 + EOR (immediate value does not match) + +Small piece of code manipulating screen-related variable. Since EOR argument does not match, it's clear that the code does something different. The similar part is trivial - not copyrightable. diff --git a/strings/2CA90085 b/strings/2CA90085 new file mode 100644 index 00000000..2c911e18 --- /dev/null +++ b/strings/2CA90085 @@ -0,0 +1,3 @@ +$2C (BIT) + LDA #$00 + STA (zeropage address does not match) + +A common trick using BIT opcode to load (or not) value into to .A and continue execution. Trivial - not copyrightable. diff --git a/strings/2CA9042CA9 b/strings/2CA9042CA9 new file mode 100644 index 00000000..8ba049f5 --- /dev/null +++ b/strings/2CA9042CA9 @@ -0,0 +1,3 @@ +$2C (BIT) + LDA #$04 + $2C (BIT) + LDA (value does not match) + +A common trick using BIT opcode to load different values (depending on a condition) to .A and continue execution. Here the values does not even fully match. Trivial - not copyrghtable. diff --git a/strings/3504F334 b/strings/3504F334 new file mode 100644 index 00000000..9d6da7fe --- /dev/null +++ b/strings/3504F334 @@ -0,0 +1,3 @@ +1.0 / sqr(2.0) (partial similarity only, does not include exponent) + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/38E90285 b/strings/38E90285 new file mode 100644 index 00000000..9b4cfbac --- /dev/null +++ b/strings/38E90285 @@ -0,0 +1,3 @@ +SEC + SBC #$02 + STA (zeropage address does not match) + +Subtract 2 from accumulator, store result somewhere (location does not match) - trivial, not copyrightable. diff --git a/strings/490FDAA2 b/strings/490FDAA2 new file mode 100644 index 00000000..9d7affdb --- /dev/null +++ b/strings/490FDAA2 @@ -0,0 +1,3 @@ +PI / 2.0 (partial similarity only, does not include exponent) + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/4C0CED4C b/strings/4C0CED4C new file mode 100644 index 00000000..f59817ae --- /dev/null +++ b/strings/4C0CED4C @@ -0,0 +1,3 @@ +JMP $ED0C + JMP (address does not match) + +Instruction and some part. Trivial - not copyrightable. diff --git a/strings/608100000000 b/strings/608100000000 new file mode 100644 index 00000000..4ce43696 --- /dev/null +++ b/strings/608100000000 @@ -0,0 +1,3 @@ +RTS (end of previous routine) + floating point constant 1.0 + +Basically a fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/61D0034C b/strings/61D0034C new file mode 100644 index 00000000..d0520aa8 --- /dev/null +++ b/strings/61D0034C @@ -0,0 +1,3 @@ +$61 + BNE (skip next instruction) + JMP (address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/61F006A56649FF8566608138AA3B29 b/strings/61F006A56649FF8566608138AA3B29 new file mode 100644 index 00000000..372fdb96 --- /dev/null +++ b/strings/61F006A56649FF8566608138AA3B29 @@ -0,0 +1,8 @@ +$61 + BEQ (offset matches) + LDA $66 + EOR #$FF + STA $66 + RTS + floating point constant 1.0 / log_e(2.0) (last byte differs, probablyy due to rounding) + +A part of trivial routine, reversing the sign of floating point accumulator, if it is not 0. Afterwards a floating point constant - a fact (generated by a specially written tool), not creative work. +Locations of the routine/constant are not creative work either - we have to preserve them to keep the compatiibility. + +Not copyrightable. + + diff --git a/strings/62666366646665667060 b/strings/62666366646665667060 new file mode 100644 index 00000000..ca4930bf --- /dev/null +++ b/strings/62666366646665667060 @@ -0,0 +1,3 @@ +$62 + ROR $63 + ROR $64 + ROR $65 + ROR $70 + RTS + +Code for dividing multi-byte integer by 2 (this time a floating point mantissa), common technique for 6502 assembler. Not creative - not copyrightable. diff --git a/strings/63856BA5 b/strings/63856BA5 new file mode 100644 index 00000000..a4d47655 --- /dev/null +++ b/strings/63856BA5 @@ -0,0 +1,3 @@ +$63 + STA $6B + LDA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/64856CA5 b/strings/64856CA5 new file mode 100644 index 00000000..1e2c0e39 --- /dev/null +++ b/strings/64856CA5 @@ -0,0 +1,3 @@ +$64 + STA $6C + LDA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/65856DA5 b/strings/65856DA5 new file mode 100644 index 00000000..648ad890 --- /dev/null +++ b/strings/65856DA5 @@ -0,0 +1,3 @@ +$65 + STA $6D + LDA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/66456E85 b/strings/66456E85 new file mode 100644 index 00000000..9c596392 --- /dev/null +++ b/strings/66456E85 @@ -0,0 +1,3 @@ +$66 + EOR $6E + STA (zeropage address does not match) + +Small piece of floating point values manipulation code (single instruction and some parts). Trivial - not copyrightable. diff --git a/strings/6649FF8566 b/strings/6649FF8566 new file mode 100644 index 00000000..e08d4fe3 --- /dev/null +++ b/strings/6649FF8566 @@ -0,0 +1,3 @@ +$66 + EOR #$FF + STA $66 + +Part of ccode reversing sign oof floating point variable. Trivial - not copyrightable. diff --git a/strings/66626663666466656670 b/strings/66626663666466656670 new file mode 100644 index 00000000..45be6917 --- /dev/null +++ b/strings/66626663666466656670 @@ -0,0 +1,3 @@ +ROR $62 + ROR $63 + ROR $64 + ROR $65 + ROR $70 + +Code for dividing multi-byte integer by 2 (this time a floating point mantissa), common technique for 6502 assembler. Not creative - not copyrightable. diff --git a/strings/6662666366646665667060 b/strings/6662666366646665667060 new file mode 100644 index 00000000..753cc7a2 --- /dev/null +++ b/strings/6662666366646665667060 @@ -0,0 +1,3 @@ +ROR $62 + ROR $63 + ROR $64 + ROR $65 + ROR $70 + RTS + +Code for dividing multi-byte integer by 2 (this time a floating point mantissa), common technique for 6502 assembler. Not creative - not copyrightable. diff --git a/strings/6A85624C b/strings/6A85624C new file mode 100644 index 00000000..c76e8180 --- /dev/null +++ b/strings/6A85624C @@ -0,0 +1,3 @@ +$6A + STA $62 + JMP (addres does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/6AE56285 b/strings/6AE56285 new file mode 100644 index 00000000..1aa15687 --- /dev/null +++ b/strings/6AE56285 @@ -0,0 +1,3 @@ +$6A + SBC $62 + STA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/6B8563A5 b/strings/6B8563A5 new file mode 100644 index 00000000..7a1b8e3a --- /dev/null +++ b/strings/6B8563A5 @@ -0,0 +1,3 @@ +$6B + STA $63 + LDA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/6B8563A562 b/strings/6B8563A562 new file mode 100644 index 00000000..d254cb6a --- /dev/null +++ b/strings/6B8563A562 @@ -0,0 +1,3 @@ +$6B + STA $63 + LDA $62 + +Small piece of code manipulating copying bytes of a well-known location (floating point accumulator) - trivial, not copyrightable. diff --git a/strings/6C8564A5 b/strings/6C8564A5 new file mode 100644 index 00000000..c6866eb3 --- /dev/null +++ b/strings/6C8564A5 @@ -0,0 +1,3 @@ +$6C + STA $64 + LDA (zeropage address does not match) + +Single instruction + some parts. Trivial - not copyrightable. diff --git a/strings/6CE56485 b/strings/6CE56485 new file mode 100644 index 00000000..8f6f6459 --- /dev/null +++ b/strings/6CE56485 @@ -0,0 +1,3 @@ +$6C + SBC $64 + STA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/6D8565A5 b/strings/6D8565A5 new file mode 100644 index 00000000..f822248f --- /dev/null +++ b/strings/6D8565A5 @@ -0,0 +1,3 @@ +$6D + STA $65 + LDA (zeropage address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/6D8565A564 b/strings/6D8565A564 new file mode 100644 index 00000000..f5704def --- /dev/null +++ b/strings/6D8565A564 @@ -0,0 +1,3 @@ +$6D + STA $65 + LDA $64 + +Small piece of code manipulating copying bytes of a well-known location (floating point accumulator) - trivial, not copyrightable. diff --git a/strings/702665266426632662 b/strings/702665266426632662 new file mode 100644 index 00000000..82e40274 --- /dev/null +++ b/strings/702665266426632662 @@ -0,0 +1,3 @@ +$70 + ROL $65 + ROL $64 + ROL $63 + ROL $62 + +Code for multiplaying multi-byte integer by 2 (this time a floating point mantissa), common technique for 6502 assembler. Not creative - not copyrightable. diff --git a/strings/803504F334813504F334808000000080317217F8 b/strings/803504F334813504F334808000000080317217F8 new file mode 100644 index 00000000..97a9130b --- /dev/null +++ b/strings/803504F334813504F334808000000080317217F8 @@ -0,0 +1,3 @@ +floating point constants: 1.0 / sqr(2.0) , sqr(2.0), -0.5, log_e(2.0) + +List of facts (generated by a specially written tool) in a well-known memory location, not a creative work. Not copyrightable. diff --git a/strings/8100000000 b/strings/8100000000 new file mode 100644 index 00000000..00e855aa --- /dev/null +++ b/strings/8100000000 @@ -0,0 +1,3 @@ +floating point constant 1.0 + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/81490FDAA283490FDAA27F00000000 b/strings/81490FDAA283490FDAA27F00000000 new file mode 100644 index 00000000..0f1bb8a9 --- /dev/null +++ b/strings/81490FDAA283490FDAA27F00000000 @@ -0,0 +1,3 @@ +floating point constants: PI / 2.0, PI * 2.0, 0.25 + +List of facts (generated by a specially written tool) in a well-known memory location, not a creative work. Not copyrightable. diff --git a/strings/82490FDA b/strings/82490FDA new file mode 100644 index 00000000..76d39a83 --- /dev/null +++ b/strings/82490FDA @@ -0,0 +1,3 @@ +floating point constant PI, last byte (lowest byte of mantissa) differs, probably due to rounding + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/83490FDAA2 b/strings/83490FDAA2 new file mode 100644 index 00000000..20cdb268 --- /dev/null +++ b/strings/83490FDAA2 @@ -0,0 +1,3 @@ +floating point constant PI * 2.0 + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/8420000000 b/strings/8420000000 new file mode 100644 index 00000000..a0fd48f2 --- /dev/null +++ b/strings/8420000000 @@ -0,0 +1,3 @@ +floating point constant 10.0 + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/8561A56585 b/strings/8561A56585 new file mode 100644 index 00000000..040db5b9 --- /dev/null +++ b/strings/8561A56585 @@ -0,0 +1,3 @@ +STA $61 + LDA $65 + STA (zeropage address does not match) + +Small piece of code manipulating copying bytes of a well-known location (floating point accumulator) - trivial, not copyrightable. diff --git a/strings/8562856385648565 b/strings/8562856385648565 new file mode 100644 index 00000000..9f626ee9 --- /dev/null +++ b/strings/8562856385648565 @@ -0,0 +1,3 @@ +STA $62 + STA $63 + STA $64 + STA $65 + +Piece of code filling the floating point mantissa bytes with constant variable - trivial, not copyrightable. diff --git a/strings/8562B003 b/strings/8562B003 new file mode 100644 index 00000000..5cd99bfa --- /dev/null +++ b/strings/8562B003 @@ -0,0 +1,3 @@ +STA $62 + BCS (offset matches) + +Small piece of floating point values manipulation code. Trivial - not copyrightable. diff --git a/strings/8563A562 b/strings/8563A562 new file mode 100644 index 00000000..d7e64cb6 --- /dev/null +++ b/strings/8563A562 @@ -0,0 +1,3 @@ +STA $63 + LDA $62 + +Small piece of code manipulating copying bytes of a well-known location (floating point accumulator) - trivial, not copyrightable. diff --git a/strings/8566A561 b/strings/8566A561 new file mode 100644 index 00000000..abfd6ab4 --- /dev/null +++ b/strings/8566A561 @@ -0,0 +1,3 @@ +STA $66 + LDA $61 + +Small piece of code manipulating copying bytes of a well-known location (floating point accumulator) - trivial, not copyrightable. diff --git a/strings/867060 b/strings/867060 new file mode 100644 index 00000000..9b5ee0ab --- /dev/null +++ b/strings/867060 @@ -0,0 +1,3 @@ +STX $70 (FACOV) + RTS + +Storing .X register in a welll-known memory location, followed by end of subroutine. Trivial - not copyrightable. diff --git a/strings/88B122 b/strings/88B122 new file mode 100644 index 00000000..cb432334 --- /dev/null +++ b/strings/88B122 @@ -0,0 +1,3 @@ +DEY + LDA ($22),Y + +Part of the loop reading data via general purpose vector variable. Not creative and fairy trivial- not copyrightable. diff --git a/strings/88B12285 b/strings/88B12285 new file mode 100644 index 00000000..b74ab76c --- /dev/null +++ b/strings/88B12285 @@ -0,0 +1,3 @@ +DEY + LDA ($22),Y + STA (zeropage address does not match) + +Part of the loop reading data via general purpose vector variable. Not creative and fairy trivial- not copyrightable. diff --git a/strings/8D00DCAD01DC b/strings/8D00DCAD01DC new file mode 100644 index 00000000..2168599f --- /dev/null +++ b/strings/8D00DCAD01DC @@ -0,0 +1,3 @@ +STA $DC00 + LDA $DC01 + +Small part of the routine manipulating I/O registers (store value in one register, fetch from another). Trivial - not copyrightable. diff --git a/strings/9080000000 b/strings/9080000000 new file mode 100644 index 00000000..ac8bd96c --- /dev/null +++ b/strings/9080000000 @@ -0,0 +1,3 @@ +floating point constant -32768.0 + +A fact (generated by a specially written tool), not creative work. Not copyrightable. diff --git a/strings/A0008470 b/strings/A0008470 new file mode 100644 index 00000000..93b1e3d6 --- /dev/null +++ b/strings/A0008470 @@ -0,0 +1,3 @@ +LDY #$00 + STY $70 + +Store 0 in a zeropage location, using .Y register. Trivial - not copyrightable. diff --git a/strings/A5619122 b/strings/A5619122 new file mode 100644 index 00000000..72e9637f --- /dev/null +++ b/strings/A5619122 @@ -0,0 +1,3 @@ +LDA $61 + STA ($22),Y + +Copy value from zeropage to some memory location pointed by a general-purpose vector. Trivial - noot copyrightable. diff --git a/strings/A56649FF b/strings/A56649FF new file mode 100644 index 00000000..45d482ce --- /dev/null +++ b/strings/A56649FF @@ -0,0 +1,3 @@ +LDA $66 + EOR #$FF + +Load a floating point value sign and reverse it - trivial, not copyrightable. diff --git a/strings/A56649FF8566 b/strings/A56649FF8566 new file mode 100644 index 00000000..25494374 --- /dev/null +++ b/strings/A56649FF8566 @@ -0,0 +1,3 @@ +LDA $66 + EOR #$FF + STA $66 + +Reversal of all the bits in a register (where 0 means positive floating point value, $FF - negative). Trivial - not copyrightable. diff --git a/strings/A56AE56285 b/strings/A56AE56285 new file mode 100644 index 00000000..88a3f800 --- /dev/null +++ b/strings/A56AE56285 @@ -0,0 +1,3 @@ +LDA $6A + SBC $62 + STA (zeropage address does not match) + +Small piece of code subtracting one floating point mantissa from another - this is a common technique to subtract numbers over 8 bits size on 6502. Not creative - not copyrightable. diff --git a/strings/A56DE56585 b/strings/A56DE56585 new file mode 100644 index 00000000..681b0e56 --- /dev/null +++ b/strings/A56DE56585 @@ -0,0 +1,3 @@ +LDA $6D + SBC $65 + STA (address does not match) + +Calculate diiff between two zeropage values, store result in another location - trivial, not copyrightable. diff --git a/strings/A56E8566 b/strings/A56E8566 new file mode 100644 index 00000000..43958604 --- /dev/null +++ b/strings/A56E8566 @@ -0,0 +1,3 @@ +LDA $6E + STA $66 + +Copy value from one zeropage location to another - trivial, not copyrightable. diff --git a/strings/A5A745AB85AB b/strings/A5A745AB85AB new file mode 100644 index 00000000..e69d8cbd --- /dev/null +++ b/strings/A5A745AB85AB @@ -0,0 +1,3 @@ +LDA $A7 + EOR $AB + STA $AB + +Small part of a routine reading from tape, calculates XOR checksum of the stream. Trivial - not copyrightable. diff --git a/strings/A5C485C2 b/strings/A5C485C2 new file mode 100644 index 00000000..f5a12df3 --- /dev/null +++ b/strings/A5C485C2 @@ -0,0 +1,3 @@ +LDA $C4 + STA $C2 + +Copy value from one zeropage location to another. Trivial - not copyrightable. diff --git a/strings/A6D8F005 b/strings/A6D8F005 new file mode 100644 index 00000000..2d6cac22 --- /dev/null +++ b/strings/A6D8F005 @@ -0,0 +1,3 @@ +LDX $D8 + BEQ (offset matches) + +Decision based whether well-known zeropage loacation is 0 or not. Trivial - not copyrightable. diff --git a/strings/A9012CA9022CA9032CA9042CA9052CA9062CA9072CA9082CA909 b/strings/A9012CA9022CA9032CA9042CA9052CA9062CA9072CA9082CA909 new file mode 100644 index 00000000..be85a90c --- /dev/null +++ b/strings/A9012CA9022CA9032CA9042CA9052CA9062CA9072CA9082CA909 @@ -0,0 +1,3 @@ +LDA #$01 + $2C + LDA #$02 + $2C + LDA #$03 + ... + +Common size optimization to set different values to a variable depending on a jump address, using BIT instruction ($2C) to skip unnecessary instruction, this time a relatively long one. Well-known technique, not creative - thus not copyrightable. diff --git a/strings/A9802CA9 b/strings/A9802CA9 new file mode 100644 index 00000000..9f95a605 --- /dev/null +++ b/strings/A9802CA9 @@ -0,0 +1,3 @@ +LDA #$80 + $2C (BIT) + LDA (value does not match) + +A common trick using BIT opcode to load different values (depending on a condition) to .A and continue execution. Here the values does not even fully match. Trivial - not copyrghtable. diff --git a/strings/B12285 b/strings/B12285 new file mode 100644 index 00000000..77d4f8a4 --- /dev/null +++ b/strings/B12285 @@ -0,0 +1,4 @@ +LDA ($22),Y + STA (zeropage address does not match) + +Instruction (accessing data via general purpose vector) + some part. Trivial, not copyyrightable. + diff --git a/strings/B1228565 b/strings/B1228565 new file mode 100644 index 00000000..85096ecf --- /dev/null +++ b/strings/B1228565 @@ -0,0 +1,3 @@ +LDA ($22),Y + STA $65 + +Small part of a routine copying memory variable to floating point accumulator (copies 1 byte) - trivial, not copyrightable. diff --git a/strings/BA200CED b/strings/BA200CED new file mode 100644 index 00000000..3ce6f608 --- /dev/null +++ b/strings/BA200CED @@ -0,0 +1,3 @@ +$BA + JSR $ED0C + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/BAC902D0 b/strings/BAC902D0 new file mode 100644 index 00000000..e135fb06 --- /dev/null +++ b/strings/BAC902D0 @@ -0,0 +1,3 @@ +$BA + CMP #$02 + BNE (offset does not match) + +Instruction + some parts. Trivial - not copyrightable. diff --git a/strings/D885F46020 b/strings/D885F46020 new file mode 100644 index 00000000..64c665fa --- /dev/null +++ b/strings/D885F46020 @@ -0,0 +1,3 @@ +$D8 + STA $F4 + RTS + JSR (address does not match) + +End of the routine (store data in a well-known zeropage location) + some parts. Trivial - not copyrightable. diff --git a/strings/E69FE69F b/strings/E69FE69F new file mode 100644 index 00000000..c28b9b68 --- /dev/null +++ b/strings/E69FE69F @@ -0,0 +1,4 @@ +INC $9F + INC $9F + +Increase value of zeropage variable (which counts the number of vectors) by 2. Trivial - not copyrightable. + diff --git a/strings/F38810F5 b/strings/F38810F5 new file mode 100644 index 00000000..d8b917cf --- /dev/null +++ b/strings/F38810F5 @@ -0,0 +1,3 @@ +$F3 + DEY + BPL (offset matches) + +Small part of the loop indexeed by .Y, counting down. Trivial - not copyrightable. diff --git a/strings/F7B0034C b/strings/F7B0034C new file mode 100644 index 00000000..ee5ded44 --- /dev/null +++ b/strings/F7B0034C @@ -0,0 +1,3 @@ +$F7 + BCS (skip the JMP) + JMP (address does not match) + +Instruction + some parts. Trivial, not copyrightable. diff --git a/strings/F7C884C8A0 b/strings/F7C884C8A0 new file mode 100644 index 00000000..bfed6dc9 --- /dev/null +++ b/strings/F7C884C8A0 @@ -0,0 +1,3 @@ +$F7 + INY + STY $C8 + LDY (immediate value does not match) + +Small piece of code manipulating screen-related variable. Similarity is very limited, there is nothing creative here - not copyrightable.