Import initial version of my work
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a3110cf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+all: interbank.disa bank0.disa
+interbank.rom: cqfd.rom
+	dd if=cqfd.rom of=interbank.rom bs=8192 skip=1 count=1
+interbank.disa: cqfd.control interbank.rom interbank.control
+	dasm05 $< > $@
+bank0.disa: bank0.control cqfd.rom interbank.control
+	dasm05 $< > $@
+	rm interbank.disa bank0.disa interbank.rom
+# vim:ft=make
diff --git a/ b/
new file mode 100644
index 0000000..b8364f8
--- /dev/null
+++ b/
@@ -0,0 +1,26 @@
+CQFD Scientus ROM disassembly and documentation project
+I have dumped the ROM of the CQFD Scientus. This is a project to disassemble the ROM and
+understand how it operates, and document the thing a bit, hopefully resulting in someone
+implementing it in MAME or something.
+This machine is designed by VTech, who at the time decided to use the CQFD brand name in
+France for some of their products.
+What you need
+- The dasmxx disassembler from
+- The ROM dump (not included here for copyright reasons)
+How it works
+- Install dasmxx (more specifically dasm05 for the 68hc05 CPU)
+- Copy the ROM in here as cqfd.rom
+- Run make
+The makefile will take care of cutting the ROM in separate pieces for each memory bank, and
+disassemble each of them with the appropriate "control" file, which adds the labels and
+comments to make the disassembly readable.
diff --git a/bank0.control b/bank0.control
new file mode 100644
index 0000000..e5e7696
--- /dev/null
+++ b/bank0.control
@@ -0,0 +1,135 @@
+Bank 0 jump table
+This will be executed while being mapped at address 4000.
+Take this into account when trying to interpret the addresses.
+b4080 uppercase_accents
+b40a0 lowercase_accents
+p40c0 routine2_and_3
+p43e2 routine4
+p4438 routine0
+p4472 routine1
+p48a6 clear_bits_4_and_5_of_r48
+p48ab routine6
+p48cf routine7
+p48f3 routine10
+p48fa routine11
+p4901 routine8
+p4927 routine9
+p49e5 test_r028f_nonzero
+p49ed routineb
+p4bd1 call_routine11(2f,00)
+p4bdf call_routine11(4f,00)
+p4bed call_routine11(2e,00)
+p4c17 routinec
+p4cc0 routine16
+p4de6 routinef_and_12
+l4e3e lda028e_is_not_1
+l4e7d lda028e_is_not_5
+l4ebc lda028e_is_not_8
+l4efb lda028e_is_not_9
+l4f3a lda028e_is_not_10
+l4f79 lda028e_is_not_12
+l4fb8 lda028e_is_not_14
+l4ff7 lda028e_is_not_17
+l5036 lda028e_is_not_2
+l5075 lda028e_is_not_4
+l50b4 lda028e_is_not_b
+l50f3 lda028e_is_not_a
+l5132 lda028e_is_not_e
+l5171 lda028e_is_not_16
+l51b0 lda028e_is_not_15
+l51ef lda028e_is_not_18
+l522e lda028e_is_not_3
+l526d lda028e_is_not_7
+l52ac lda028e_is_not_c
+l52eb lda028e_is_not_f
+l532a lda028e_is_not_11
+l532e lda028e_is_not_1b
+l536d lda028e_is_not_13
+l53ac lda028e_is_not_d
+l13eb lda028e_is_not_19
+l542a lda028e_is_not_6
+p54c3 routined
+l54ed r67_neq_r68
+l5516 r68_eq_0
+l5532 r68_eq_23_or_57
+l5536 r68_neq_0_and_r67_eq_23_or_57
+l554c r68_eq_20
+l5550 r68_neq_0_and_r67_eq_20
+l5561 some_loop
+l5590 convert_to_lowercase
+l5598 symbol_converted_shift_unshift
+l55c5 r67_eq_r68
+l55e7 clear_4c_and_return
+l55eb p4bfb_return
+b5615 keyboard_data
+b56c9 symbols_unshifted
+b56de symbols_shifted
+s56f3 vowels
+b5714 qwerty_azerty
+b5736 azerty_qwerty
+p5758 test_if_vowel
+l5759 vowel_search_loop
+l5772 not_vowel
+l5778 is_vowel
+Convert a character (passed in A) to transform the QWERTY keyboard
+mapping into AZERTY, or conversely (the VTech mapping is just swapping
+some keys)
+p577c convert_qwerty_azerty
+Test if a character (passed in A) is a keyboard symbol.
+If it is, convert it to the other character on the key (shifted/unshifted), and set the carry.
+Otherwise, clear the carry and return the character unchanged.
+Also handles the special characters ED/EF, maybe caps lock on/off?
+p57a7 is_keyboard_symbol_shift_unshift
+l57a8 search_in_symbols_unshifted
+l57c3 a_found_in_symbols_unshifted
+l57d1 not_special_ed
+l57d4 a_not_found_in_symbols_unshifted
+l57d8 search_in_symbols_shifted
+l57f3 a_not_found_in_symbols_shifted
+l57f9 a_found_in_symbols_shifted
+l58e07 not_special_ef
+l5808 p57a7_return
+p588c routinee
+p5b98 routine13
+p5c52 routine15
+p5cef routine14
diff --git a/cqfd.control b/cqfd.control
new file mode 100644
index 0000000..010da30
--- /dev/null
+++ b/cqfd.control
@@ -0,0 +1,427 @@
+l0005 mistery_reg_5
+l001e mistery_reg_1e
+l0029 rombank_select_4000
+l002a bank_select_8000
+l002b rambank_select_d000
+l002d rombank_select_c000
+l0044 mistery_reg_44
+l004e idx8
+l0051 mistery_reg_51
+l0052 mistery_reg_52
+l0054 mistery_reg_54
+l0055 mistery_reg_55
+l0058 mistery_reg_58
+l0072 mistery_var_72_hi
+l0073 mistery_var_72_low
+l0074 mistery_bitfield_74
+l01e9 bank2_savea
+l023a idx16_hi_save_bank1
+l023b idx16_lo_save_bank1
+l0240 some_array_indexed_by_0282
+l0270 idx16_savehi
+l0271 idx16_savelo
+l0272 p2xxx_interrupt_status_save
+l0278 r4e_save
+l0282 index_for_0240
+l0283 p3xxx_interrupt_status_save
+l0284 r72_save2_hi
+l0285 r72_save2_lo
+l0286 r72_save_hi
+l0287 r72_save_lo
+Start of resident ROM area
+This area is always mapped at address 2000, and contains generic code,
+including code that allows to switch ROM banks and jump between them.
+At least part of the addresses before 2000 are RAM and hardware
+registers. So the part of the ROM before here is only accessible
+when mapped at 4000 as bank 0.
+Jumptable for interbank routines.
+These are used often or implement quite low level things to make the CPU usable.
+They are always mapped in and can be easily called this way.
+l283c goto_3883
+l2845 goto_28a5
+l2848 goto_2c7c
+l284b goto_2a05
+l2869 do_call_routine15_bank0_with_265eq0_and_264eq6
+l286f goto_3ab6
+l2872 goto_3ac2
+l288d goto_38e3
+l2896 setbit7_7f_and_call_2845
+l289e clear_7f_and_call_2845
+l28c0 p28a5_restore_interrupts_and_continue
+l28c3 p28a5_interrupts_are_clear
+l28d6 p28a5_continue
+p29f7 call_routine15_bank0_with_265eq0_and_264eq6
+l2a0f p2a05_interrupts_are_off
+l2a14 p2a05_endif_interrupts
+l2a2a r78_is_zero
+l2b6b r78_is_not_0
+l2b86 p2a05_return_0
+l2b8d r78_is_not_1
+l2ba5 p2a05_return_0_v1
+l2bac r78_is_not_2
+l2bc0 p2a05_return_0_v2
+l2beb r78_is_not_1e
+l2c0d x_is_not_47
+l2c1a x_is_not_48
+l2c27 x_is_not_49
+l2c34 x_is_not_4a
+l2c86 p2c7c_interrupts_are_off
+l2ca1 r78_is_0
+l2ca8 r267_higher_than_46
+l2d23 r267_is_not_47
+l2d9e r267_is_not_48
+l2e19 r267_is_not_49
+l2e94 r267_is_not_4a
+l2f0b r267_lower_than_46
+l2f10 r78_is_not_0
+l2f19 r78_is_not_1
+l2f22 r78_is_not_2
+l2f33 r267_more_than_3f
+l2f57 r267_more_than_3c_or_r78_is_3
+l2f78 r267_less_than_31
+p31e2 pusha
+l31f2 pusha_int_already_disabled
+p31fe popa
+l320e popa_int_already_disabled
+p321a pushx
+l322c pushx_int_already_disabled
+p323a popx
+l324b popx_int_already_disabled
+p3258 stack_reset
+l3261 stack_reset_int_already_disabled
+p3266 inc_u16_at_x
+p326c inc_s24_at_x_maybe
+l3275 p326c_x_is_positive_inc_lsb
+l3279 p326c_lsb_overflow_inc_msb
+l3280 p326c_msb_overflow
+l3288 p326c_x_is_negative
+l3290 p326c_lsb_overflow_neg
+l329f p326c_x_is_c0
+l32ad p326c_return
+p32b1 lda_x4f
+p32b7 lda_x4f_inc
+p32bd sta_x4f
+p32c3 sta_x4f_inc
+p32c9 call_334b_with_x4e
+p32cf call_33f5_with_x4e
+p32d5 call_33fc_with_x4e
+p32db call_34ac_with_x4e
+k32e1 Load A from 16 bit address pointed by X
+p32e1 lda_x16
+l32f7 p32e1_interrupts_are_disabled
+k3309 Load A from 16 bit address pointed by X and increment address
+p3309 lda_x16_increment
+k3310 Store A to 16 bit address pointed by X
+p3310 sta_x16
+l332c p3310_interrupts_are_disabled
+k3344 Store A to 16 bit address pointed by X and increment address
+p3344 sta_x16_increment
+l33a2 p334b_interrupts_are_disabled
+l3456 p33fc_interrupts_are_disabled
+p34b3 delayloop_ax
+p34bb delayloop_aax
+p34ca delayloop_ax_with_timeout_bit5_reg44
+p34d9 delayloop_aax_with_timeout
+Call a subroutine in another bank
+      Input:
+      $63 contains the bank number
+      $64-$65 contains the routine address
+p34ef far_call
+l3514 p34ef_interrupts_are_disabled
+p3535 io_wait_something
+l356e p3553_interrupts_are_disabled
+Detect memory banks 20 (cartridge?) and 40 (RAM?)
+Map them at 8000 and check for known patterns or writable space.
+Return cartridge subtype in X
+p3585 detect_banks
+k3585 Save currently selected bank
+k358a Select bank 20
+k358f Check for pattern 55AA at address 8100
+l35a9 process_type32_bank
+l35ea not_type32
+l35c5 not_subtype02
+l35cc not_subtype04
+l35d3 not_subtype05
+l35da not_subtype06
+l35e1 not_subtype07
+l35ee process_type31_bank
+l360a not_84
+l3612 not_04
+l36ea not_type323132
+l361a no_pattern_match_8100
+k3632 Detected 55AA11 at 8000 - Return 9
+l3636 no_pattern_match_8000
+k3636 Map bank 40 and check for RAM
+l3659 ramcheck_success
+k365f Detected RAM - Return 8
+l3663 ramcheck_error
+k3666 Detected nothing - Return 0
+l3669 detect_banks_return
+p3759 isupper
+l3771 p3759_want_bank0
+l3787 lower_than_A
+l3789 p3759_return
+l3791 lower_than_Z
+p3793 islower
+p37cd toupper
+p380e tolower
+p384f call_3677_then_do_same_as_3883
+l388f want_bank0
+l389d p3883_interrupts_are_disabled
+l38a3 p3883_restore_banks
+l38b0 r4c_is_not_clear
+p38b4 clear_r4d_and_r4c
+l38bd p38b4_interrupts_are_disabled
+p38db get_not_51_bit4
+l38e1 bit4_is_set
+l3903 p43_loop_enter
+l3905 p43_loop_repeat
+l3924 p43_interrupts_are_disabled
+l3935 p43_return
+p3938 do_393f_then_38e3
+p3ac2 clear_bit7_of_74_and_call_3b9d
+l3acc p3ac2_bit7_of_74_is_already_clear
+p3acd save_r72_16
+l3adc p3acd_interrupts_are_clear
+l3b20 p3ae7_interrupts_are_clear
+l3b62 p3b58_interrupts_are_disabled
+l3b67 p3b58_interrupts_endif
+l3ba7 p3b9d_interrupts_are_clear
+l3bac p3b9d_continue
+l3bb4 p3b9d_loop
+p3cb0 mul_r72_by_5_mod3_something_store_in_281
+l3cd4 p3cb0_return
+p3cd5 rti_3cd5
+l3de6 rti_3de6
+l3dfa rti_3dfa
+p3dfb maybe_reset_vector
+l3e6b ram_clear_loop_0000
+l3e72 preserve_address_52
+l3e76 ram_clear_loop_0100
+l3e7c ram_clear_loop_0200
+l3e89 ram_clear_loop_022b
+l3e8f ram_clear_loop_0800
+l3e96 ram_clear_loop_08f0
+l3f19 not_55aa
+l3f1e yes_55aa
+b3fc0 rom_header
+c3fd8 rom_mainbank_vectors
+s3ff0 copyright_vtech
+Start of bank 1.
+p4a00 bank1_routine1
+p4a2e bank1_routine2
+p4a5c bank1_routine3
+p4a8a bank1_routine4
+p4ab8 bank1_routine5
+p4ae6 bank1_routine6
+p4b14 bank1_routine7
+p4b42 bank1_routine8
+p4b70 bank1_routine9
+p4b9e bank1_routinea
+l4cb5 b1ra_loop
+p4d28 bank1_routine16
+p4eca bank1_routine18
+p5074 bank1_routineb
+p512d bank1_routinec
+p5265 bank1_routined
+p5269 bank1_routinee
+p526b bank1_routinef
+p52e4 bank1_routine10
+p53f2 bank1_routine11
+p53fc bank1_routine12
+p548e bank1_routine13
+p5520 bank1_routine15
+p5574 bank1_routine14
+p55a0 bank1_routine0
+p5b55 bank1_routine17
+l5b88 r52_is_c0
+l5b93 r52_is_40
+l5b9c bank1_routine17_tail
+p8042 bank2_routine9
+p8049 bank2_routine4
+p8059 bank2_routine0
+p9ddc bank2_routine1
+pb9c3 bank2_routine3
+paff0 bank2_routine5
+pb271 bank2_routine6
+pb9b8 bank2_routine7
+p9ca3 bank2_routine8
+pad12 bank2_routinea
+pacc2 bank2_routineb
+pad62 bank2_routinec
+pacd2 bank2_routined
+pad72 bank2_routinee
+pace2 bank2_routinef
+pad82 bank2_routine10
+pacf2 bank2_routine11
+pad92 bank2_routine12
diff --git a/interbank.control b/interbank.control
new file mode 100644
index 0000000..b299317
--- /dev/null
+++ b/interbank.control
@@ -0,0 +1,113 @@
+Keyboard flags are stored here.
+Bit 0 switches between QWERTY and AZERTY
+Bit 1 ???
+Bit 2 ???
+Bits 3 and 4 ??? maybe capslock. They can be 10 or 01, no other values?
+Bit 5 appears to be unused so far.
+Bit 6 ???
+Bit 7 ???
+l0047 keyboard_config_bits
+l004d save_x_kbd
+l004f idx16_hi
+l0050 idx16_lo
+A 4-byte zone in RAM where several routines will poke two instructions
+and then execute them, to implement missing features of the CPU such
+as indirect register load and stores.
+l005f scratch_area
+l0228 save_x
+k0235 Memory used for passing arguments to functions
+l0235 arg_4
+l0236 arg_3
+l0237 arg_2
+l0238 arg_1
+l0239 arg_0
+Store a pointer to the next area (??? to 90) which is used as a stack
+to save the A and X registers. In 6805 there are no instructions to
+push or pop these registers on the call stack, which has a very
+limited size anyway.
+l0069 reg_stackptr
+l0090 reg_stackbase
+l2000 call_routine0_bank0
+l2005 call_routine1_bank0
+l2019 b0r5_clear_bits_4_and_5_of_r48
+l2028 call_routine8_bank0
+l2032 b0ra_test_r028f_nonzero
+l203c call_routinec_bank0
+l2041 call_routined_bank0
+l2046 call_routinee_bank0
+l2055 call_routine11_bank0
+l205f call_routine13_bank0
+l2069 call_routine15_bank0
+l209d call_bank0_routine
+l20c0 call_routine0_bank1
+l20d4 call_routine4_bank1
+l20e3 call_routine7_bank1
+l20e8 call_routine8_bank1
+l20ed call_routine9_bank1
+l2129 call_routine15_bank1
+l2133 call_routine17_bank1
+l2138 call_routine18_bank1
+l215d call_bank1_routine
+l2180 call_routine0_bank2
+l21ad call_routine9_bank2
+l221d call_bank2_routine
+l2240 call_routine0_bank3
+l22dd call_bank3_routine
+l2300 call_routine0_bank4
+l239d call_bank4_routine
+l23c0 call_routine0_bank5
+l245d call_bank5_routine
+l2480 call_routine0_bank6
+l24b2 call_routinea_bank6
+l251d call_bank6_routine
+l2540 call_routine0_bank20
+l25dd call_bank20_routine
+l2600 call_routine0_bank21
+l269d call_bank21_routine
+l26c0 call_routine0_bank63
+l27ad call_bank63_routine
+l27d3 PUSHA
+l27d6 POPA
+l27d9 PUSHX
+l27dc POPX
+l27df FAR_CALL
+l27e2 LDA_IDX16
+k27e2 Load A with value pointed by 16bit pointer at 4F
+l27e5 STA_IDX16
+l27e8 LDA_IDX16_INC
+l27eb STA_IDX16_INC
+l27fa LDA_X16
+k27fa Load A with value pointed by 16bit pointer at X
+l27fd STA_X16
+l2800 LDA_X16_INC
+l2803 STA_X16_INC
+l2812 INC16_AT_X
+l2830 ISUPPER
+l2833 ISLOWER
+l2836 TOUPPER
+l2839 TOLOWER