0000: 0000: 0000: ; IC Tester Software 0000: ; 0000: ; (c) 2006 Kio 0000: ; 0000: ; start: 2006-08-24 0000: ; modified: 2006-09-28 0000: ; 0000: ; Version 0.1 0000: 0000: 0000: 0000: #target rom ; ((inserted by zasm)) 0000: #code 0,$4000 0000: 0000: data_size equ $400 0000: data_buffer equ $5B00 0000: 0000: #data data_buffer, data_size 0000: 0000: 0000: 0000: port equ -1 - $10 ; Bit 4 = 0 0000: port_A8 equ port - $0100 ; Pin 1 .. 8 0000: port_A9 equ port - $0200 ; Pin 9 .. 16 0000: port_A10 equ port - $0400 ; Pin 17 .. 24 0000: port_A11 equ port - $0800 ; Pin 25 .. 32 0000: port_A12 equ port - $1000 ; Pin 33 .. 40 0000: port_A13 equ port - $2000 ; Pin 41 .. 48 0000: all_ports equ port - $3F00 0000: 0000: 0000: 0000: 0000: 0000: 0000: 0000: ; ---------------------------------- 0000: ; RST 0: Reset 0000: ; ---------------------------------- 0000: F3 di ; Security only 0001: C36B00 jp cold_start_ctd 0004: 0004: 0004: 0004: ; ---------------------------------- 0004: ; RST 1: Print inline text 0004: ; mod: iy 0004: ; ---------------------------------- 0004: FFFFFFFF defs $08 - $ 0008: 0008: print_msg_no_exx: 0008: print_msg: 0008: E3 ex hl,(sp) 0009: CDC204 call print_text_hl_no_exx 000C: 23 inc hl 000D: E3 ex hl,(sp) 000E: C9 ret 000F: 000F: 000F: 000F: ; ---------------------------------- 000F: ; RST 2: Save BC,DE,HL 000F: ; and prepare restauration after RET 000F: ; ---------------------------------- 000F: FF defs $10 - $ 0010: 0010: save_registers: 0010: C34B00 jp save_registers_ctd 0013: 0013: DDE9 jp_ix: jp (ix) 0015: FDE9 jp_iy: jp (iy) 0017: 0017: 0017: 0017: ; ---------------------------------- 0017: ; RST 3: Save BC',DE',HL' 0017: ; and prepare restauration after RET 0017: ; ---------------------------------- 0017: FF defs $18 - $ 0018: 0018: save_exx_registers: 0018: C35900 jp save_exx_registers_ctd 001B: 001B: D5 jp_de: push de 001C: C9 ret 001D: C5 jp_bc: push bc 001E: C9 ret 001F: E9 jp_hl: jp (hl) 0020: 0020: 0020: 0020: ; ---------------------------------- 0020: ; RST 4 0020: ; ---------------------------------- 0020: defs $20 - $ 0020: 0020: C1 vip: pop bc ; bc = vip pc 0021: vip_iy: ; auxiliary entry 0021: FD217112 ld iy,vip_dis ; vip dispatcher entry 0025: FDE9 jp (iy) 0027: 0027: 0027: 0027: ; ---------------------------------- 0027: ; RST 5 0027: ; ---------------------------------- 0027: FF defs $28 - $ 0028: 0028: 0028: 0028: ; ---------------------------------- 0028: ; RST 6 0028: ; ---------------------------------- 0028: FFFFFFFF 002C: FFFFFFFF defs $30 - $ 0030: 0030: 0030: 0030: ; ---------------------------------- 0030: ; RST 7: Interrupt Routine 0030: ; ---------------------------------- 0030: FFFFFFFF 0034: FFFFFFFF defs $38 - $ 0038: F5 push af 0039: C5 push bc 003A: D5 push de 003B: E5 push hl 003C: CD3220 call irpt_timer 003F: CD981B call irpt_scan_keyboard 0042: CDEE1F call irpt_pin_display 0045: E1 pop hl 0046: D1 pop de 0047: C1 pop bc 0048: F1 pop af 0049: FB ei 004A: C9 ret 004B: 004B: 004B: 004B: #if 0 004B: ; ---------------------------------- 004B: ; NMI Routine 004B: ; ---------------------------------- 004B: defs 66 - $ 004B: retn 004B: #endif 004B: 004B: 004B: 004B: 004B: 004B: 004B: ; ---------------------------------- 004B: ; Save registers BC .. HL 004B: ; and prepare stack with routine address 004B: ; to restore the registers after return 004B: ; 004B: ; All registers except IY are preserved on entry. 004B: ; BC, DE, HL and IY are restored after exit. 004B: ; All other registers are preserved on exit. 004B: ; 004B: ; IY is restored after exit, but it is modified on entry! 004B: ; 004B: ; in: BC, DE, HL, IY 004B: ; out: -- 004B: ; mod: -- 004B: 004B: save_registers_ctd: 004B: FDE3 ex iy,(sp) 004D: 004D: E5 push hl 004E: D5 push de 004F: C5 push bc 0050: 0050: CD1500 call jp_iy 0053: 0053: C1 pop bc 0054: D1 pop de 0055: E1 pop hl 0056: FDE1 pop iy 0058: 0058: C9 ret 0059: 0059: 0059: 0059: 0059: ; ---------------------------------- 0059: ; Save registers BC' .. HL' 0059: ; and prepare stack with routine address 0059: ; to restore the registers after return 0059: ; 0059: ; this allows to call exx'ing routines 0059: ; from a no_exx routine. 0059: ; 0059: ; in: BC', DE', HL' 0059: ; out: -- 0059: ; mod: IY 0059: 0059: save_exx_registers_ctd: 0059: FDE3 ex iy,(sp) 005B: 005B: D9 exx 005C: E5 push hl 005D: D5 push de 005E: C5 push bc 005F: D9 exx 0060: 0060: CD1500 call jp_iy 0063: 0063: D9 exx 0064: C1 pop bc 0065: D1 pop de 0066: E1 pop hl 0067: D9 exx 0068: 0068: FDE1 pop iy 006A: C9 ret 006B: 006B: 006B: 006B: 006B: 006B: 006B: 006B: 006B: 006B: #include "rst.ass" 006B: 006B: 006B: 006B: RAMTOP data 2 ; $0000 für 48k 006B: 006B: 006B: ; -------------------------------------------------------- 006B: ; SYSTEMSTART 006B: ; -------------------------------------------------------- 006B: 006B: cold_start_ctd: 006B: 006B: ; Reset Tester: 006B: 006B: 01EFC0 ld bc,all_ports ; IC Tester: alle Pins := 0, +5V an Pin 48 := off 006E: ED71 out (bc),0 0070: 0070: ; Speicher löschen & prüfen: 0070: 0070: 3E01 ld a,blue ; ear/mic := 0, border := color 1 0072: D3FE out ($FE),a 0074: FD217B00 ld iy,cold_1 ; return address 0078: C34A18 jp ram_test ; test RAM -> hl = ramtop 007B: 22005B cold_1 ld (RAMTOP),hl ; ramtop 007E: F9 ld sp,hl ; Stack 007F: 007F: ; Speicherverwaltung: 007F: 007F: 25 dec h ; -256 for stack 0080: EB ex hl,de ; de = end of available ram 0081: 21AA5C ld hl,data_end ; hl = start of available ram 0084: CD770E call mem_init ; [hl .. ram .. [de 0087: CD8D18 call init_errors ; set oomem handler 008A: CDC603 call init_print ; Print-Routinen 008D: CD7012 call init_vip 0090: 0090: ; Interrupts: 0090: 0090: CD3120 call init_timer ; Timer 0093: CD5A1B call init_keyboard ; Scan Keyboard 0096: CD1D1E call init_pin_display ; IC-Grafik 0099: ED46 im 0 ; => RST 7 009B: FB ei ; => Interrupt := ON 009C: 009C: ; Systemstart 009C: 009C: CDF81E call ic_test_tester_present 009F: C3BE00 jp main ; does not return 00A2: 00A2: 00A2: 00A2: 00A2: ; -------------------------------------------------------- 00A2: ; Warte auf Taste und verzweige gemäß Tabelle 00A2: ; 00A2: ; Dem Handler wird in A der Keycode übergeben, 00A2: ; z.B. für Handler, die mehrere Keycodes behandeln können. 00A2: ; wird kein passender Keycode in der Tabelle gefunden, 00A2: ; wird der letzte Handler als 'catch-it-all' aufgerufen. 00A2: ; Mit 'ret' kehrt der Handler zum Aufrufer zurück. 00A2: ; 00A2: ; Format der Tabelle: 00A2: ; call inkey_dispatcher 00A2: ; n * { db keycode 00A2: ; dw hander_proc_address } 00A2: ; db 0 ; end marker 00A2: ; dw catch_it_all_handler 00A2: ; 00A2: ; in: Tabelle folgt inline 00A2: ; out: from handler 00A2: ; mod: af bc de hl 00A2: 00A2: inkey_dispatcher: 00A2: CD5E1B call wait_inkey ; -> a 00A5: 4F ld c,a ; c=key 00A6: 00A6: E1 pop hl ; -> table 00A7: 00A7: 7E sk1 ld a,(hl) ; a = keycode 00A8: 00A8: 23 inc hl 00A9: 5E ld e,(hl) 00AA: 23 inc hl 00AB: 56 ld d,(hl) ; de -> handler proc 00AC: 23 inc hl 00AD: 00AD: A7 and a ; end of table? 00AE: 280A jr z,sk3 ; => jump to catch-it-all 00B0: 00B0: B9 cp c ; gefunden ? 00B1: 20F4 jr nz,sk1 ; nein 00B3: 00B3: ; keycode gefunden => skip to end of table 00B3: AF xor a 00B4: BE sk2 cp (hl) 00B5: 23 inc hl 00B6: 23 inc hl 00B7: 23 inc hl 00B8: 20FA jr nz,sk2 00BA: 00BA: ; end of table reached 00BA: 79 sk3 ld a,c ; a=key 00BB: E5 push hl ; ret_addr := return to caller 00BC: EB ex hl,de ; hl -> handler 00BD: E9 jp (hl) ; jump to handler, ret will return to caller 00BE: 00BE: 00BE: 00BE: main: 00BE: main_menu: 00BE: CD1D1E call stop_pin_display 00C1: 00C1: CF rst print_msg 00C2: 0670 defb ctl_setattr,yellow_paper+black+bright 00C4: 02 defb ctl_cls 00C5: 00C5: 0627 defb ctl_setattr,green_paper+white 00C7: 0D0420 defb 13,ctl_setcol,32 00CA: 49432054 00CE: 65737465 00D2: 7220762E 00D6: 302E3120 00DA: 2D202863 00DE: 29203230 00E2: 3036204B 00E6: 696F2021 defm "IC Tester v.0.1 - (c) 2006 Kio !" 00EA: 0630 defb ctl_setattr,yellow_paper+black 00EC: 00EC: 0D0D0420 00F0: 28312920 00F4: 52414D20 00F8: 54657374 defb 13,13,ctl_setcol,32, "(1) RAM Test" 00FC: 0D0D0420 0100: 28322920 0104: 4550524F 0108: 4D205265 010C: 61642026 0110: 20546573 0114: 74 defb 13,13,ctl_setcol,32, "(2) EPROM Read & Test" 0115: 0D0D0420 0119: 28332920 011D: 54544C20 0121: 4964656E 0125: 74696679 0129: 20262054 012D: 657374 defb 13,13,ctl_setcol,32, "(3) TTL Identify & Test" 0130: 0D0D0420 0134: 28342920 0138: 46726565 013C: 20546573 0140: 74204D6F 0144: 6465 defb 13,13,ctl_setcol,32, "(4) Free Test Mode" 0146: 0D0D0420 014A: 28352920 014E: 53797374 0152: 656D2049 0156: 6E666F defb 13,13,ctl_setcol,32, "(5) System Info" 0159: 0D0D0420 015D: 28362920 0161: 53617665 0165: 202F204C 0169: 6F616420 016D: 49432044 0171: 6566696E 0175: 6974696F 0179: 6E73 defb 13,13,ctl_setcol,32, "(6) Save / Load IC Definitions" 017B: 0D0D0420 017F: 28522920 0183: 52657365 0187: 74 defb 13,13,ctl_setcol,32, "(R) Reset" 0188: ;defb 13,13,ctl_setcol,32, "(T) Text VDU Test" 0188: 0D0D0420 018C: 28562920 0190: 56495020 0194: 54657374 defb 13,13,ctl_setcol,32, "(V) VIP Test" 0198: 00 defb 0 0199: 0199: ED7B005B mm1 ld sp,(RAMTOP) 019D: CDE518 call print_error_message ; falls vorhanden 01A0: 01A0: CDA200 call inkey_dispatcher 01A3: 31 defb '1' 01A4: C001 defw ram_test_menu 01A6: 32 defb '2' 01A7: 6702 defw eprom_test_menu 01A9: 33 defb '3' 01AA: 1603 defw ttl_test_menu 01AC: 34 defb '4' 01AD: 7F26 defw free_test_menu 01AF: 35 defb '5' 01B0: BE23 defw system_info 01B2: 52 defb 'R' 01B3: 0000 defw $0000 01B5: 54 defb 'T' 01B6: D403 defw text_speed_test 01B8: 56 defb 'V' 01B9: 4E21 defw vip_test 01BB: 00 defb 0 01BC: 9901 defw mm1 01BE: 18D9 jr mm1 01C0: 01C0: 01C0: ram_test_menu: 01C0: CD1D1E call stop_pin_display 01C3: 01C3: CF rst print_msg 01C4: 0668 defb ctl_setattr,cyan_paper+black+bright 01C6: 02 defb ctl_cls 01C7: 0627 defb ctl_setattr,green_paper+white 01C9: 01C9: 0D0420 defb 13,ctl_setcol,32 01CC: 52414D20 01D0: 54657374 01D4: 6572 defm "RAM Tester" 01D6: 0628 defb ctl_setattr,cyan_paper+black 01D8: 01D8: 0D0D0420 01DC: 28302920 01E0: 4261636B 01E4: 20746F20 01E8: 4D61696E 01EC: 204D656E 01F0: 75 defb 13,13,ctl_setcol,32, "(0) Back to Main Menu" 01F1: 0D0D0420 01F5: 28312920 01F9: 53656C65 01FD: 63742052 0201: 414D2054 0205: 797065 defb 13,13,ctl_setcol,32, "(1) Select RAM Type" 0208: 0D0D0420 020C: 28322920 0210: 52756E20 0214: 42616420 0218: 43656C6C 021C: 20546573 0220: 74 defb 13,13,ctl_setcol,32, "(2) Run Bad Cell Test" 0221: 0D0D0420 0225: 28332920 0229: 52756E20 022D: 52656672 0231: 65736820 0235: 54657374 defb 13,13,ctl_setcol,32, "(3) Run Refresh Test" 0239: 0D0D0420 023D: 28342920 0241: 4C6F6164 0245: 20494320 0249: 44656669 024D: 6E697469 0251: 6F6E73 defb 13,13,ctl_setcol,32, "(4) Load IC Definitions" 0254: 00 defb 0 0255: 0255: ED7B005B rt1 ld sp,(RAMTOP) 0259: CDE518 call print_error_message ; falls vorhanden 025C: 025C: CDA200 call inkey_dispatcher 025F: 30 defb '0' 0260: BE00 defw main_menu 0262: 00 defb 0 0263: 5502 defw rt1 0265: 18EE jr rt1 0267: 0267: 0267: 0267: eprom_test_menu: 0267: CD1D1E call stop_pin_display 026A: 026A: CF rst print_msg 026B: 0668 defb ctl_setattr,cyan_paper+black+bright 026D: 02 defb ctl_cls 026E: 0627 defb ctl_setattr,green_paper+white 0270: 0270: 0D0420 defb 13,ctl_setcol,32 0273: 4550524F 0277: 4D205465 027B: 73746572 defm "EPROM Tester" 027F: 0628 defb ctl_setattr,cyan_paper+black 0281: 0281: 0D0D0420 0285: 28302920 0289: 4261636B 028D: 20746F20 0291: 4D61696E 0295: 204D656E 0299: 75 defb 13,13,ctl_setcol,32, "(0) Back to Main Menu" 029A: 0D0D0420 029E: 28312920 02A2: 53656C65 02A6: 63742045 02AA: 50524F4D 02AE: 20547970 02B2: 65 defb 13,13,ctl_setcol,32, "(1) Select EPROM Type" 02B3: 0D0D0420 02B7: 28322920 02BB: 456D7074 02BF: 79205465 02C3: 7374 defb 13,13,ctl_setcol,32, "(2) Empty Test" 02C5: 0D0D0420 02C9: 28332920 02CD: 48657820 02D1: 45646974 02D5: 6F72 defb 13,13,ctl_setcol,32, "(3) Hex Editor" 02D7: 0D0D0420 02DB: 28342920 02DF: 53617665 02E3: 20446174 02E7: 61 defb 13,13,ctl_setcol,32, "(4) Save Data" 02E8: 0D0D0420 02EC: 28352920 02F0: 4C6F6164 02F4: 20494320 02F8: 44656669 02FC: 6E697469 0300: 6F6E73 defb 13,13,ctl_setcol,32, "(5) Load IC Definitions" 0303: 00 defb 0 0304: 0304: ED7B005B et1 ld sp,(RAMTOP) 0308: CDE518 call print_error_message ; falls vorhanden 030B: 030B: CDA200 call inkey_dispatcher 030E: 30 defb '0' 030F: BE00 defw main_menu 0311: 00 defb 0 0312: 0403 defw et1 0314: 18EE jr et1 0316: 0316: 0316: 0316: ttl_test_menu: 0316: CD1D1E call stop_pin_display 0319: 0319: CF rst print_msg 031A: 0668 defb ctl_setattr,cyan_paper+black+bright 031C: 02 defb ctl_cls 031D: 0627 defb ctl_setattr,green_paper+white 031F: 031F: 0D0420 defb 13,ctl_setcol,32 0322: 54544C20 0326: 54657374 032A: 6572 defm "TTL Tester" 032C: 0628 defb ctl_setattr,cyan_paper+black 032E: 032E: 0D0D0420 0332: 28302920 0336: 4261636B 033A: 20746F20 033E: 4D61696E 0342: 204D656E 0346: 75 defb 13,13,ctl_setcol,32, "(0) Back to Main Menu" 0347: 0D0D0420 034B: 28312920 034F: 53656C65 0353: 63742054 0357: 797065 defb 13,13,ctl_setcol,32, "(1) Select Type" 035A: 0D0D0420 035E: 28322920 0362: 4175746F 0366: 64657465 036A: 63742054 036E: 797065 defb 13,13,ctl_setcol,32, "(2) Autodetect Type" 0371: 0D0D0420 0375: 28332920 0379: 43616C63 037D: 2E204368 0381: 65636B73 0385: 756D defb 13,13,ctl_setcol,32, "(3) Calc. Checksum" 0387: 0D0D0420 038B: 28342920 038F: 53617665 0393: 20446174 0397: 61 defb 13,13,ctl_setcol,32, "(4) Save Data" 0398: 0D0D0420 039C: 28352920 03A0: 4C6F6164 03A4: 20494320 03A8: 44656669 03AC: 6E697469 03B0: 6F6E73 defb 13,13,ctl_setcol,32, "(5) Load IC Definitions" 03B3: 00 defb 0 03B4: 03B4: ED7B005B tt1 ld sp,(RAMTOP) 03B8: CDE518 call print_error_message ; falls vorhanden 03BB: 03BB: CDA200 call inkey_dispatcher 03BE: 30 defb '0' 03BF: BE00 defw main_menu 03C1: 00 defb 0 03C2: B403 defw tt1 03C4: 18EE jr tt1 03C6: 03C6: 03C6: 03C6: 03C6: print_start equ $ 03C6: ; tab-8 03C6: 03C6: 03C6: ; -------------------------------------------------------- 03C6: ; P R I N T - V D U 03C6: ; -------------------------------------------------------- 03C6: 03C6: ; Betrachtungen zu HL + bitnr. C vs. HL + bitmaske C 03C6: ; 03C6: ; Die Text-VDU speichert die aktuelle Printposition in HL und C, 03C6: ; wobei HL auf das Pixelbyte im Bildschirm zeigt und C die Maske 03C6: ; für das exakte Pixel ist. 03C6: ; 03C6: ; Alternativ dazu wäre es möglich, die exakte Pixelposition in C 03C6: ; als Bitnummer zu speichern. Das geht grundsätzlich schneller: 03C6: ; zum setzen eines Bits kann 'set n,(hl)' benutzt werden, was 03C6: ; schneller ist als 'ld a,(hl)' + 'or c' + 'ld (hl),a' und 03C6: ; zusätzlich das A-Register unbenutzt lässt. 03C6: ; Leider kennt die Z80 keine Bitbefehle mit berechneter Bitnummer - 03C6: ; die Bitnummer ist immer im Opcode hart kodiert. Deshalb muss 03C6: ; der Bit-Set-Opcode gepatcht werden und deshalb muss die Routine 03C6: ; in's Ram und der Aufruf und der Patch des Opcodes wird immer umständlicher. 03C6: ; 03C6: ; Deshalb ist letztendlich - zumindest für Rom-Code - die Version 03C6: ; mit der Bitmaske in C günstiger, und jetzt hier auch so implementiert. 03C6: 03C6: ; init_print -- 03C6: ; print_reset -- 03C6: ; print_calc_ctl_args A -- A 03C6: ; print_push_state -- 03C6: ; print_yes_no cy -- 03C6: ; print_no -- nc 03C6: ; print_yes -- cy 03C6: ; print_dec_a A -- 03C6: ; print_dec HL -- 03C6: ; print_dec5 HL -- 03C6: ; print_dec4 HL -- 03C6: ; print_dec3 HL -- 03C6: ; print_dec2 HL -- 03C6: ; print_dec1 HL -- 03C6: ; print_hex4 HL -- 03C6: ; print_hex2 A -- 03C6: ; print_hex1 A -- 03C6: ; print_bin16 HL -- 03C6: ; print_bin8 A -- 03C6: ; print_bin4 A -- 03C6: ; print_char A -- 03C6: ; print_msg inline -- 03C6: ; print_text_hl HL -- HL++ 03C6: ; print_locate B C -- 03C6: ; print_setattr A -- 03C6: ; scroll_screen -- 03C6: ; scroll_screen_up -- 03C6: ; show_scroll_and_wait_for_key -- 03C6: ; print_find_char_wrap HL BC -- DE 03C6: ; print_find_word_wrap HL BC -- DE 03C6: ; print_calc_print_width HL -- HL BC 03C6: ; print_add_print_width HL BC -- HL BC 03C6: ; print_calc_print_width_char A -- A 03C6: ; calc_row_b_col_c_from_hlc HL C -- B C 03C6: ; calc_hlc_from_row_b_col_c B C -- HL C 03C6: 03C6: 03C6: 03C6: p_scratch data 10 03C6: 03C6: 03C6: 03C6: 03C6: 03C6: 03C6: ; ------------------------------- 03C6: ; Data 03C6: 03C6: print_first_data data 0 03C6: print_hl data 2 03C6: print_c data 1 03C6: print_attr data 1 03C6: print_flags data 1 03C6: print_scrollcount data 1 03C6: print_logptr data 2 03C6: print_pending_ctl data 2 03C6: print_last_data data 0 03C6: 03C6: ; print_flags: 03C6: pbit_narrow equ 0 ; bit in print_flags: narrow spacing: omit first spacing column 03C6: pbit_inverse equ 1 ; bit in print_flags: print inverse: set pixels for 0-bits in glyph 03C6: pbit_bold equ 2 ; bit in print_flags: print inverse: set pixels for 0-bits in glyph 03C6: pbit_log equ 3 ; bit in print_flags: log all printing (print_logptr)++ 03C6: pbit_pending_ctl equ 4 ; bit in print_flags: control code pending, awaiting argument byte 03C6: 03C6: 03C6: ; Attribute: 03C6: 03C6: black equ 0 03C6: blue equ 1 03C6: red equ 2 03C6: magenta equ 3 03C6: green equ 4 03C6: cyan equ 5 03C6: yellow equ 6 03C6: white equ 7 03C6: 03C6: pen equ 1 03C6: paper equ 8 03C6: bright equ $40 03C6: flashing equ $80 03C6: 03C6: black_paper equ black * paper 03C6: blue_paper equ blue * paper 03C6: red_paper equ red * paper 03C6: magenta_paper equ magenta*paper 03C6: green_paper equ green * paper 03C6: cyan_paper equ cyan * paper 03C6: yellow_paper equ yellow* paper 03C6: white_paper equ white * paper 03C6: 03C6: 03C6: 03C6: ; Control Codes: 03C6: ; note: must match pc_jumpblock! 03C6: 03C6: ctl_eot equ 0 ; end of text 03C6: ctl_home equ 1 ; locate 0,0 03C6: ctl_cls equ 2 ; clear screen mit print_attr, set border, home cursor 03C6: ctl_locate equ 3 ; set cursor to row, col (req. 2 argument characters) 03C6: ctl_setcol equ 4 ; set cursor to col (req. 1 argument character) 03C6: ctl_setrow equ 5 ; set cursor to row (req. 1 argument character) 03C6: ctl_setattr equ 6 ; set paper, pen, bright + flashing (req. 1 argument character) 03C6: ctl_setpen equ 7 ; set pen (req. 1 argument character) 03C6: ctl_setpaper equ 8 ; set paper (req. 1 argument character) 03C6: ctl_clrcols equ 9 ; clear n pixel columns, don't move cursor (req. 1 argument character) 03C6: ctl_tab equ 10 ; set cursor to next tab position (n*8*8 pixel) 03C6: ; equ 11,12 03C6: ctl_newline equ 13 ; set cursor to start of next line (may scroll) 03C6: ctl_inverse equ 14;15 ; +0/+1: reset/set bright attr 03C6: ctl_narrow equ 16;17 ; +0/+1: reset/set bright attr 03C6: ctl_bold equ 18;19 ; +0/+1: reset/set bold attr 03C6: ctl_log equ 20;21 ; +0/+1: reset/set log-to-mem flag 03C6: ctl_flash equ 22;23 ; +0/+1: reset/set flash attr 03C6: ctl_bright equ 24;25 ; +0/+1: reset/set bright attr 03C6: 03C6: ctl_clr2eol equ 26 ; clear to end of line, don't move cursor 03C6: ; equ 27,28,29,30,31 03C6: 03C6: 03C6: 03C6: ; ---------------------------------------------------- 03C6: ; Initialize Text VDU 03C6: ; 03C6: ; in: -- 03C6: ; out: -- 03C6: ; mod: iy 03C6: 03C6: init_print: 03C6: 03C6: ; Reset internal state: 03C6: ;call print_reset ; z.Zt. ein Nop. 03C6: 03C6: ; clear screen, home cursor and set color attributes: 03C6: CF rst print_msg 03C7: 01 defb ctl_home ; init print_hl & print_c 03C8: 0638 defb ctl_setattr, white_paper+black ; init print_attr 03CA: 00 defb 0 03CB: C9 ret 03CC: 03CC: 03CC: 03CC: ; ---------------------------------------- 03CC: ; Reset Text VDU 03CC: ; 03CC: ; reset flags, discard pending ctl code waiting for argument. 03CC: ; does not clear screen, home cursor or set color attributes. 03CC: ; 03CC: ; in: -- 03CC: ; out: -- 03CC: ; mod: af 03CC: 03CC: print_reset_no_exx: 03CC: print_reset: 03CC: 97 sub a 03CD: 32105B ld (print_flags),a ; switch off special modes, kill pending ctl arg 03D0: 32115B ld (print_scrollcount),a ; "scroll?" count 03D3: C9 ret 03D4: 03D4: 03D4: 03D4: ; --------------------------------------------------------- 03D4: ; Speed Test 03D4: ; 03D4: ; set both breakpoints and examine T cycle count 03D4: ; in zxsp or other emulator. 03D4: ; 03D4: ; 2006-09-17: currently takes ~69000 T cycles 03D4: ; this will vary with every change made to the print routine. 03D4: 03D4: #if 1 03D4: text_speed_test 03D4: 76 halt 03D5: F3 di 03D6: CF rst print_msg ; <- breakpoint here 03D7: 01 defb ctl_home 03D8: 54686520 03DC: 51756963 03E0: 6B204272 03E4: 6F776E20 03E8: 466F7820 03EC: 4A756D70 03F0: 6564204F 03F4: 76657220 03F8: 54686520 03FC: 4C617A79 0400: 20446F67 0404: 732E00 defm "The Quick Brown Fox Jumped Over The Lazy Dogs.",$00 0407: FB ei ; <- breakpoint here 0408: 76 halt 0409: 76 halt 040A: C3BE00 jp main_menu 040D: #endif 040D: 040D: 040D: ; ------------------------------------------ 040D: ; Ask, whether a ctl code requires arguments 040D: ; 040D: ; in: A = ctl code 040D: ; out: A = no. of arguments. 040D: ; mod: AF 040D: 040D: print_calc_ctl_args: 040D: FE0A cp ctl_tab 040F: 300C jr nc,pq0 ; ctl >= tab: alle 0 arguments 0411: 0411: FE03 cp ctl_locate 0413: 3808 jr c,pq0 ; code < locate: eot, home, cls: alle 0 args 0415: 2803 jr z,pq2 ; locate: 2 args 0417: 0417: 3E01 pq1 ld a,1 ; setcol, setrow, setattr,setpen,setpaper: 1 arg 0419: C9 ret 041A: 3E02 pq2 ld a,2 041C: C9 ret 041D: AF pq0 xor a 041E: C9 ret 041F: 041F: 041F: 041F: 041F: ; ---------------------------------------- 041F: ; save text vdu state on stack 041F: ; 041F: ; in: -- 041F: ; out: -- 041F: ; mod: af 041F: 041F: print_push_state: 041F: D9 exx 0420: 010A00 ld bc, print_last_data - print_first_data 0423: 210C5B ld hl, print_first_data 0426: CD3510 call mem_heap_push_data_no_exx 0429: D9 exx 042A: C9 ret 042B: 042B: 042B: 042B: ; ---------------------------------------- 042B: ; restore text vdu state from stack 042B: ; 042B: ; in: -- 042B: ; out: -- 042B: ; mod: af 042B: 042B: print_pop_state: 042B: D9 exx 042C: 110C5B ld de, print_first_data 042F: CD5210 call mem_heap_pop_data_no_exx 0432: D9 exx 0433: C9 ret 0434: 0434: 0434: ; ------------------------------------------------------------ 0434: ; print "yes" or "no" depending on cy-flag: 0434: ; 0434: ; cy -> print "yes" 0434: ; nc -> print "no" 0434: ; 0434: ; in: cy-flag 0434: ; out: cy-flag 0434: ; mod: -- 0434: 0434: print_yes_no: 0434: 3806 jr c,print_yes 0436: ;jr nc,print_no 0436: 0436: 0436: 0436: ; ------------------------------------------------------------ 0436: ; print "no" & ret nc 0436: ; 0436: ; in: -- 0436: ; out: f: cy = nc 0436: ; mod: f 0436: 0436: print_no: 0436: CF rst print_msg 0437: 6E6F00 defm "no",$00 043A: A7 and a ; enforce nc 043B: C9 ret 043C: 043C: 043C: 043C: ; ------------------------------------------------------------ 043C: ; print "yes" & ret c 043C: ; 043C: ; in: -- 043C: ; out: f: cy = c 043C: ; mod: f 043C: 043C: print_yes: 043C: CF rst print_msg 043D: 79657300 defm "yes",$00 0441: 37 scf ; enforce cy 0442: C9 ret 0443: 0443: 0443: 0443: ; ------------------------------------------------------------ 0443: ; print unsigned decimal number 0443: ; print a with auto-sized field width 0443: ; 0443: ; in: a = number 0443: ; out: -- 0443: ; mod: af 0443: 0443: print_dec_a: 0443: D7 rst save_registers 0444: 6F ld l,a 0445: 2600 ld h,0 0447: 1801 jr pd1 0449: 0449: 0449: 0449: ; ------------------------------------------------------------ 0449: ; print unsigned decimal number 0449: ; print hl with auto-sized field width 0449: ; 0449: ; in: hl = number 0449: ; out: -- 0449: ; mod: af 0449: 0449: print_dec: 0449: D7 rst save_registers 044A: 044A: 11025B pd1 ld de,p_scratch 044D: CD5820 call decstr ; max. 5 char 0450: EB pd2 ex hl,de 0451: 3600 ld (hl),0 0453: 21025B ld hl,p_scratch 0456: 186A jr print_text_hl 0458: 0458: 0458: ; ------------------------------------------------------------ 0458: ; print signed decimal number 0458: ; print hl with auto-sized field width 0458: ; 0458: ; in: hl = number 0458: ; out: -- 0458: ; mod: af 0458: 0458: print_vz_dec: 0458: D7 rst save_registers 0459: 0459: 11025B ld de,p_scratch 045C: CD4920 call vzdecstr ; max. 6 char 045F: 18EF jr pd2 0461: 0461: 0461: ; ------------------------------------------------------------ 0461: ; print word as 4 hex chars 0461: ; 0461: ; in: hl = number 0461: ; out: -- 0461: ; mod: af 0461: 0461: print_hex4: 0461: D7 rst save_registers 0462: 0462: 11025B ld de,p_scratch 0465: CDA520 call hexstr4 0468: 18E6 jr pd2 046A: 046A: 046A: 046A: ; ------------------------------------------------------------ 046A: ; print byte as 2 hex chars 046A: ; 046A: ; in: a = number 046A: ; out: -- 046A: ; mod: af 046A: 046A: print_hex2: 046A: D7 rst save_registers 046B: 046B: 11025B ld de,p_scratch 046E: CDAC20 call hexstr2 0471: 18DD jr pd2 0473: 0473: 0473: 0473: ; ------------------------------------------------------------ 0473: ; print hex char 0473: ; 0473: ; in: a = number (lower nibble only) 0473: ; out: -- 0473: ; mod: af 0473: 0473: print_hex1: 0473: E60F and $0f 0475: C630 add '0' 0477: FE3A cp '9'+1 0479: 3841 jr c,print_char 047B: C607 add 7 047D: 183D jr print_char 047F: 047F: 047F: 047F: ; ------------------------------------------------------------ 047F: ; print word as 16 binary chars 047F: ; 047F: ; in: hl = number 047F: ; out: -- 047F: ; mod: af 047F: 047F: print_bin16: 047F: E5 push hl 0480: 7C ld a,h 0481: CD8604 call print_bin8 0484: E1 pop hl 0485: 7D ld a,l 0486: ;jr print_bin8 0486: 0486: 0486: 0486: ; ------------------------------------------------------------ 0486: ; print byte as 8 binary chars 0486: ; 0486: ; in: a = number 0486: ; out: -- 0486: ; mod: af 0486: 0486: print_bin8: 0486: D7 rst save_registers 0487: 11025B ld de,p_scratch 048A: CDCB20 call binstr8 048D: 18C1 jr pd2 048F: 048F: 048F: 048F: ; ------------------------------------------------------------ 048F: ; print nibble as 4 binary chars 048F: ; 048F: ; in: a = number (lower nibble only) 048F: ; out: -- 048F: ; mod: af 048F: 048F: print_bin4: 048F: D7 rst save_registers 0490: 11025B ld de,p_scratch 0493: CDDA20 call binstr4 0496: 18B8 jr pd2 0498: 0498: 0498: 0498: ; ------------------------------------------- 0498: ; Save and restore af,bc,de,hl, print_hl and print_c 0498: ; 0498: ; for caller: 0498: ; in: AF,B passed to called routine 0498: ; HL passed to called routine in DE 0498: ; out: -- 0498: ; mod: IY 0498: ; 0498: ; called routine: 0498: ; in: AF,B from caller 0498: ; HL,C from print_hl and print_c 0498: ; DE caller's HL 0498: ; out: HL,C for print_hl and print_c 0498: ; mod: AF,BC,DE,HL,IY 0498: 0498: ; in the called routine DE is the caller's HL. 0498: ; if the called routine wishes to return a value in the caller's HL, 0498: ; then it may exit with a jump to access_return_de. 0498: 0498: access_hlc: 0498: FDE3 ex iy,(sp) 049A: 049A: F5 push af 049B: C5 push bc 049C: D5 push de 049D: EB ex hl,de 049E: 049E: 210E5B ld hl,print_c 04A1: 4E ld c,(hl) 04A2: 2A0C5B ld hl,(print_hl) 04A5: 04A5: D5 push de ; caller's hl 04A6: CD1500 call jp_iy 04A9: D1 pop de ; caller's hl 04AA: 04AA: 79 ahlc1 ld a,c 04AB: 320E5B ld (print_c),a 04AE: 220C5B ld (print_hl),hl 04B1: 04B1: EB ex hl,de 04B2: D1 pop de 04B3: C1 pop bc 04B4: F1 pop af 04B5: 04B5: FDE1 pop iy 04B7: C9 ret 04B8: 04B8: 04B8: ; return but preserve DE for caller's HL: 04B8: 04B8: access_return_de: 04B8: F1 pop af ; drop ret addr 04B9: F1 pop af ; drop de 04BA: 18EE jr ahlc1 04BC: 04BC: 04BC: 04BC: ; ------------------------------------------- 04BC: ; print single character 04BC: ; 04BC: ; in: a = char 04BC: ; out: -- 04BC: ; mod: IY 04BC: 04BC: print_char_no_exx: 04BC: print_char: 04BC: CD9804 call access_hlc 04BF: C3DE05 jp up_print_char_a_at_hl_bit_c 04C2: 04C2: 04C2: 04C2: ; --------------------------------------------- 04C2: ; print text 04C2: ; 04C2: ; --> Restart-Vektor: RST print_msg 04C2: ; 04C2: ; in: mit 0-Byte abgeschlossener Text folgt inline 04C2: ; out: -- 04C2: ; mod: iy 04C2: 04C2: #if 0 04C2: print_msg_no_exx: 04C2: print_msg: 04C2: ex hl,(sp) 04C2: call print_text_hl_no_exx 04C2: inc hl 04C2: ex hl,(sp) 04C2: ret 04C2: #endif 04C2: 04C2: 04C2: 04C2: ; ---------------------------------------------- 04C2: ; print text 04C2: ; 04C2: ; in: hl -> 0-terminierter Text 04C2: ; out: hl++ -> $00 04C2: ; mod: hl, iy 04C2: 04C2: print_text_hl_no_exx: 04C2: print_text_hl: 04C2: CD9804 call access_hlc ; hl -> my.de -> hl 04C5: 04C5: 1A pm_1 ld a,(de) 04C6: A7 and a 04C7: 28EF jr z,access_return_de ; exit, but return DE -> caller's HL 04C9: 13 inc de 04CA: D5 push de 04CB: CDDE05 call up_print_char_a_at_hl_bit_c 04CE: D1 pop de 04CF: 18F4 jr pm_1 04D1: 04D1: 04D1: 04D1: ; ---------------------------------------------- 04D1: ; print text 04D1: ; 04D1: ; in: hl -> Text 04D1: ; c = Text length 04D1: ; out: -- 04D1: ; mod: b=0, iy, af' 04D1: 04D1: print_text_hlc_no_exx: 04D1: print_text_hlc: 04D1: 0600 ld b,0 04D3: ;jr print_text_hlbc_no_exx 04D3: 04D3: 04D3: ; ---------------------------------------------- 04D3: ; print text 04D3: ; 04D3: ; in: hl -> Text 04D3: ; bc = Text length 04D3: ; out: -- 04D3: ; mod: iy, af' 04D3: 04D3: print_text_hlbc_no_exx: 04D3: print_text_hlbc: 04D3: 08 ex af,af' 04D4: 79 ld a,c ; a' = c = inner counter 04D5: 3C inc a ; ++a wg. dec a; jr nz 04D6: 08 ex af,af' 04D7: 04D7: CD9804 call access_hlc ; hl -> my.de -> hl 04DA: 04DA: 04 inc b ; bc=counters; ++b wg. djnz 04DB: C5 push bc ; b 04DC: 1809 jr pt_2 04DE: 04DE: C5 pt_11 push bc 04DF: 08 pt_1 ex af,af' 04E0: 04E0: 1A ld a,(de) 04E1: 13 inc de 04E2: D5 push de 04E3: CDDE05 call up_print_char_a_at_hl_bit_c 04E6: D1 pop de 04E7: 04E7: 08 pt_2 ex af,af' 04E8: 3D dec a 04E9: 20F4 jr nz,pt_1 04EB: 79 ld a,c 04EC: C1 pop bc ; pop b, preserve c 04ED: 4F ld c,a 04EE: 10EE djnz pt_11 04F0: 04F0: C9 ret 04F1: 04F1: 04F1: 04F1: ; ------------------------------------------------------------ 04F1: ; Locate Textcursor at Row B, Column C 04F1: ; Setup print_hl and print_c 04F1: ; 04F1: ; if row B >= 24, then the screen is scrolled 04F1: ; until row fits in screen 04F1: ; 04F1: ; in: B = row [0..255] 04F1: ; C = col [0..255] 04F1: ; out: B = row [0..23] (adjusted) 04F1: ; mod: af, b, iy 04F1: 04F1: print_locate_no_exx: 04F1: print_locate: 04F1: 78 ld a,b 04F2: FE18 cp 24 04F4: DA6408 jp c,print_set_row_b_and_col_c 04F7: CD3105 call scroll_screen_save_exx 04FA: 05 dec b 04FB: 18F4 jr print_locate 04FD: 04FD: v_locate: ; opcode v_locate -- 04FD: E1 pop hl ; l=row; e=col 04FE: 7B ld a,e ; l=row; a=col 04FF: D1 pop de ; de = new top value 0500: C5 push bc ; sp:pc 0501: 45 ld b,l ; b=row 0502: 4F ld c,a ; c=col 0503: CDF104 call print_locate 0506: C32000 jp vip ; -> pop bc; ld iy,vip_dis; jp(iy) 0509: 0509: 0509: ; ------------------------------------------------------------ 0509: ; Locate Textcursor at Row A 0509: ; Setup print_hl and print_c 0509: ; 0509: ; if row A >= 24, then the screen is scrolled 0509: ; until row fits in screen 0509: ; 0509: ; in: A = row [0..23] 0509: ; out: -- 0509: ; mod: af,iy 0509: 0509: print_setrow: 0509: FE18 cp 24 050B: 3808 jr c,pc_l4 050D: F5 push af 050E: CD3105 call scroll_screen_save_exx 0511: F1 pop af 0512: 3D dec a 0513: 18F4 jr print_setrow 0515: 0515: C5 pc_l4 push bc 0516: 08 ex af,af' 0517: CD2E08 call print_get_row_b_and_col_c 051A: 08 ex af,af' 051B: 47 ld b,a 051C: CD6408 call print_set_row_b_and_col_c 051F: C1 pop bc 0520: C9 ret 0521: 0521: 0521: 0521: ; ------------------------------------------------------------ 0521: ; Locate Textcursor at Column A 0521: ; Setup print_hl and print_c 0521: ; 0521: ; in: A = col [0..255] 0521: ; out: -- 0521: ; mod: af 0521: 0521: print_setcol: 0521: C5 push bc 0522: 08 ex af,af' 0523: CD2E08 call print_get_row_b_and_col_c 0526: 08 ex af,af' 0527: 4F ld c,a 0528: CD6408 call print_set_row_b_and_col_c 052B: C1 pop bc 052C: C9 ret 052D: 052D: 052D: 052D: ; ------------------------------------------------------------ 052D: ; Set color attributes for subsequent text 052D: ; 052D: ; in: A = Attr 052D: ; out: -- 052D: ; mod: -- 052D: 052D: print_setattr: 052D: 320F5B ld (print_attr),a 0530: C9 ret 0531: 0531: 0531: 0531: 0531: ; ------------------------------------------------------------ 0531: ; Scroll screen up 0531: ; 0531: ; scrolls screen up by 1 character row 0531: ; scrolls 23 rows and clears bottom row with print_attr 0531: ; scrolls pixels and attributes 0531: ; printing position etc. are not updated 0531: ; 0531: ; in: -- 0531: ; out: -- 0531: ; mod: af, iy 0531: 0531: scroll_screen_save_exx: 0531: DF rst save_exx_registers 0532: 0532: scroll_screen: 0532: 3A115B ld a,(print_scrollcount) 0535: 3D dec a 0536: F23E05 jp p,ss1 0539: 0539: CD4C05 call show_scroll_and_wait_for_key 053C: 3E17 ld a,24 -1 053E: 053E: 32115B ss1 ld (print_scrollcount),a 0541: 0541: scroll_screen_up: 0541: D7 rst save_registers 0542: 210040 ld hl,$4000 ; screen start 0545: 012018 ld bc,24*256+32 ; 24 rows, 32 columns 0548: C3AF0D jp scroll_cbox_up_quick 054B: 054B: 054B: 054B: 054B: 054B: 054B: ; ------------------------------------------------------------ 054B: ; Display "scroll?" and wait for key 054B: ; 054B: ; in: -- 054B: ; out: -- 054B: ; mod: af, iy 054B: 054B: show_scroll_and_wait_for_key_save_exx: 054B: DF rst save_exx_registers 054C: 054C: show_scroll_and_wait_for_key: 054C: D7 rst save_registers 054D: 054D: 010601 ld bc,1*256 + 6 ; rows = 1; cols = 6 0550: 21FA50 ld hl,$5000+8*32 -6 ; HL -> screen 0553: CDD20C call scr_save_pixels 0556: CD410C call clear_pixels 0559: CD270E call calc_attr_hl_for_pixel_hl 055C: CD030D call scr_save_attributes 055F: CD640C call clear_attributes 0562: CD1F04 call print_push_state 0565: 0565: CDCC03 call print_reset 0568: CF rst print_msg 0569: 0317D0 defb ctl_locate, 23, 256-6*8 056C: 0617 defb ctl_setattr, white + red_paper 056E: 7363726F 0572: 6C6C3F00 defm "scroll?",$00 0576: CD5B1B call wait_newkey 0579: 0579: CD2B04 call print_pop_state 057C: CD7B0D call scr_restore_attributes 057F: C3410D jp scr_restore_pixels 0582: 0582: 0582: 0582: ; ------------------------------------------------------------ 0582: ; Determine text fitting within a given maximum size. 0582: ; Text break at word boundary 0582: ; Returned printable text may be 0 bytes long! 0582: ; 0582: ; Note: if the entire 64k of memory did not contain any code <= ' ' or '-' 0582: ; then this routine would loop forever. But luckily this routine itself contains them. :-) 0582: ; 0582: ; in: HL -> text to print, terminated with 0 0582: ; BC = max. print width 0582: ; out: DE -> first not fitting character (0/ctl_code/' '/behind '-') 0582: ; mod: AF, DE 0582: 0582: print_find_word_wrap: 0582: 0582: CD9E05 call print_find_char_wrap 0585: 1A ld a,(de) 0586: FE21 cp 33 0588: D8 ret c ; return de -> ' ' or ctl code or 0 0589: 0589: 1B pctw1 dec de ; step back 058A: 1A ld a,(de) 058B: FE20 cp ' ' 058D: 2805 jr z,pctw3 ; return de -> ' ' 058F: 058F: FE2D cp '-' 0591: 20F6 jr nz,pctw1 0593: 13 inc de ; return de -> behind '-' 0594: 0594: ; Word break found. Check for negative size: 0594: ; (if de stepped back beyond start of text) 0594: 0594: 7A pctw3 ld a,d ; d muss >= h sein 0595: 94 sub h 0596: 2002 jr nz,pctw4 0598: 0598: ; hi-bytes sind identisch 0598: 7B ld a,e ; e muss >= l sein 0599: 95 sub l 059A: ;ret z ; hl = de 059A: 059A: D0 pctw4 ret nc ; de >= hl 059B: 5D54 ld de,hl ; de < hl => de := hl 059D: C9 ret 059E: 059E: 059E: 059E: ; ------------------------------------------------------------ 059E: ; Determine text fitting within a given maximum size. 059E: ; Text break at character boundary. 059E: ; Returned printable text may be 0 bytes long! 059E: ; 059E: ; in: HL -> text to print, terminated with 0 059E: ; BC = max. print width 059E: ; out: DE -> behind last fitting character 059E: ; mod: AF, DE 059E: 059E: print_find_char_wrap: 059E: C5 push bc 059F: 059F: 78 ld a,b 05A0: 2F cpl 05A1: 47 ld b,a 05A2: 79 ld a,c 05A3: 2F cpl 05A4: 4F ld c,a ; bc := -1 -bc 05A5: 05A5: 5D54 ld de,hl 05A7: CDB005 call print_add_print_width 05AA: EB ex hl,de 05AB: C1 pop bc 05AC: C9 ret 05AD: 05AD: 05AD: 05AD: ; ------------------------------------------------------------ 05AD: ; Calc print width for text string (hl)++ 05AD: ; calculates actual print width with current settings for 05AD: ; narrow spacing and bold (TODO, bold NIMP) 05AD: ; 05AD: ; Print width is calculated up to the terminating 0-byte 05AD: ; or up to the first encountered control code. 05AD: ; 05AD: ; on return HL points behind the last counted character, 05AD: ; that is, to the terminating 0-byte or a control code. 05AD: ; 05AD: ; if print_add_print_width is called with a negative start value in BC 05AD: ; then print_add_print_width also exits when incrementing BC reaches 0. 05AD: ; then HL points to the character which caused the overflow and the 05AD: ; calculated print width is too long by the print width of this character. 05AD: ; 05AD: ; in: HL -> text to print, terminated with 0 05AD: ; out: BC = print width 05AD: ; HL -> behind last counted character 05AD: ; mod: AF, BC, HL 05AD: 05AD: print_calc_print_width: 05AD: 010000 ld bc,0 ; counter 05B0: 05B0: print_add_print_width: 05B0: 7E pcpw ld a,(hl) 05B1: FE20 cp 32 05B3: D8 ret c ; control code => return with hl -> aborting code 05B4: 23 inc hl 05B5: 05B5: CDC105 call print_calc_print_width_char ; a -- a 05B8: 05B8: 81 add c 05B9: 4F ld c,a 05BA: 30F4 jr nc,pcpw 05BC: 04 inc b 05BD: 20F1 jr nz,pcpw 05BF: 05BF: ; BC >= 0: return pointer to not fitting character. 05BF: 2B dec hl 05C0: C9 ret 05C1: 05C1: 05C1: 05C1: ; ------------------------------------------------------------ 05C1: ; Calc print width for character A 05C1: ; TODO: bold printing (not yet implemented): probably +1 pixel 05C1: ; 05C1: ; in: A = character to print 05C1: ; out: A = print width 05C1: ; mod: AF 05C1: 05C1: print_calc_print_width_char: 05C1: 05C1: FE20 cp ' ' 05C3: 3817 jr c,pc_dd ; control 05C5: 05C5: D9 exx 05C6: 05C6: 4F ld c,a 05C7: CD9808 call calc_glyph_address ; -> hl 05CA: EB ex hl,de ; de -> this char 05CB: 05CB: 79 ld a,c 05CC: 3C inc a 05CD: CD9808 call calc_glyph_address ; hl -> next char 05D0: 05D0: 7D ld a,l 05D1: 93 sub e ; a = exact width 05D2: 3C inc a ; for character spacing 05D3: 05D3: 21105B ld hl,print_flags 05D6: CB46 bit pbit_narrow,(hl) ; narrow => 1 pixel spacing 05D8: 05D8: D9 exx 05D9: 05D9: C0 ret nz 05DA: 05DA: 3C inc a ; normal => 2 pixel spacing 05DB: C9 ret 05DC: 05DC: 97 pc_dd sub a 05DD: C9 ret ; return 0 for control code 05DE: 05DE: 05DE: 05DE: ; ------------------------------------------------------------ 05DE: ; ------------------------------------------------------------ 05DE: ; Internal Routines 05DE: ; ------------------------------------------------------------ 05DE: ; ------------------------------------------------------------ 05DE: 05DE: 05DE: 05DE: ; ------------------------------------------------------------ 05DE: ; Print char a at address hl using bit c/8 05DE: ; 05DE: ; in: HL,C = Printposition 05DE: ; A = Char 05DE: ; out: HL,C = Printposition, aktualisiert 05DE: ; mod: AF, BC, DE, HL 05DE: 05DE: up_print_char_a_at_hl_bit_c: 05DE: EB ex hl,de ; de -> screen byte 05DF: 21105B ld hl,print_flags ; log printing ? 05E2: CB5E bit pbit_log,(hl) 05E4: 280B jr z,pc_aa 05E6: 05E6: 2A125B ld hl,(print_logptr) 05E9: 77 ld (hl),a 05EA: 23 inc hl 05EB: 22125B ld (print_logptr),hl 05EE: 21105B ld hl,print_flags 05F1: 05F1: CB66 pc_aa bit pbit_pending_ctl,(hl) ; hl = print_flags 05F3: 2806 jr z,pc_ab 05F5: CBA6 res pbit_pending_ctl,(hl) 05F7: 2A145B ld hl,(print_pending_ctl) 05FA: E9 jp (hl) 05FB: 05FB: FE20 pc_ab cp ' ' 05FD: 3868 jr c,pc_d ; control 05FF: 05FF: ; calc glyph address 05FF: 87 add a,a ; *2 0600: 21750A ld hl,charset_ptr -2*33 ; hl -> glyph pointer table 0603: 85 add a,l 0604: 6F ld l,a 0605: 3001 jr nc,$+3 0607: 24 inc h 0608: 7E ld a,(hl) 0609: 23 inc hl 060A: 66 ld h,(hl) 060B: 6F ld l,a ; hl -> glyph, de preserved. 060C: EB ex hl,de ; de -> glyph, hl->screen byte 060D: 060D: ; print char de at address hl using mask c 060D: ; increments hl and rotates c 060D: 060D: up_print_char_de_at_hl_bit_c: 060D: 060D: 3A105B ld a,(print_flags) 0610: CB47 bit pbit_narrow,a 0612: CC5506 call z,print_add_spacing 0615: 0615: 1A ld a,(de) ; 1st glyph col w/o own start-marker 0616: E6FE and $FE ; remove bit 0 = start-of-glyph marker 0618: 0618: E5 pc_ba push hl 0619: 47 ld b,a 061A: CD270E call calc_attr_hl_for_pixel_hl ; set attribute 061D: 3A0F5B ld a,(print_attr) 0620: 77 ld (hl),a 0621: 78 ld a,b 0622: E1 pop hl 0623: 0623: 47 pc_b ld b,a 0624: CB0F rrc a 0626: 382D jr c,print_add_spacing ; bit 0 set => next char 0628: 281C jr z,pc_z ; Byte B muss != 0 sein, sonst kein Abbruch! 062A: 062A: ; ------------------------------------------- 062A: ; Paint Pixel Column HLC with Glyph Byte B: 062A: ; Byte B muss != 0 sein sonst kein Abbruch... 062A: 062A: 7C pc_c ld a,h ; make pixel row sub address valid 062B: F607 or 7 ; make valid 062D: 67 ld h,a ; pixel werden von unten nach oben geplottet 062E: 062E: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 062E: ; Laufzeit für rst print_msg( ctl_home,"The Quick Brown Fox Jumped Over The Lazy Dogs.",$00 ) 062E: ; 48k: 68144 T 062E: ; 16k: 69107 T <- Laufzeitdifferenz alleine durch Stack im contended Ram! 062E: ; 062E: ; note: 'jr' ist bei allen Sprüngen günstiger als 'jp' 062E: ; Das unterste Pixel wird nicht in der Schleife, sondern vorab separat getestet. 062E: ; Das erspart 'dec h' (vorab) & 'inc h' (in der Schleife) und der Test lohnt sich meist, 062E: ; weil das unterste Pixel nur bei Unterlängen, also selten gesetzt ist. 062E: 062E: ;inc h 062E: ;dec h 062E: CB20 sla b ; teste unterstes Pixel. das ist meist nicht gesetzt, 0630: 3805 jr c,pc_i ; außer bei Unterlängen. Der Extratest lohnt sich! 0632: 0632: 25 pc_a dec h ; nächste Pixelzeile 0633: CB20 sla b ; nächstes Pixel 0635: 30FB jr nc,pc_a ; Pixel ist 0 => next Pixel 0637: 280A pc_i jr z,pc_h ; Rest ist 0 => set pixel & fertig 0639: 0639: 7E pc_g ld a,(hl) ; Rest ist nicht 0 => set Pixel und weiter 063A: B1 or c 063B: 77 ld (hl),a 063C: 063C: 25 pc_a2 dec h ; next pixel row 063D: CB20 sla b ; next pixel 063F: 30F1 jr nc,pc_a ; Pixel ist 0 => next Pixel 0641: 20F6 jr nz,pc_g ; Rest ist nicht 0 => set Pixel und weiter 0643: 0643: 7E pc_h ld a,(hl) ; Rest ist 0 => set pixel & fertig 0644: B1 or c 0645: 77 ld (hl),a 0646: 0646: ; ---- End of Paint 1 Pixel Column ---- 0646: 0646: CB09 pc_z rrc c ; next col 0648: 13 inc de ; next glyph col 0649: 1A ld a,(de) 064A: 30D7 jr nc,pc_b ; cy flag von: 'rrc c' 064C: 064C: ; next screen byte 064C: 2C inc l 064D: 20C9 jr nz,pc_ba 064F: 064F: ; next line && next block 064F: CD5A06 call pc_e 0652: 1A ld a,(de) 0653: 18C3 jr pc_ba 0655: 0655: 0655: print_add_spacing: ; add character spacing to hl/c 0655: CB09 rrc c 0657: D0 ret nc 0658: 2C inc l 0659: C0 ret nz 065A: 065A: ; next line && next block 065A: 7C pc_e ld a,h 065B: C608 add 8 ; next block 065D: 67 ld h,a 065E: FE58 cp $58 0660: D8 ret c 0661: ; end of screen 0661: 21E050 ld hl,$50E0 0664: C33105 jp scroll_screen_save_exx 0667: 0667: 0667: ; control code 0667: 0667: EB pc_d ex hl,de ; hl -> screen byte 0668: E61F pc_f and a,31 ; a := code [0 ... 31] 066A: 87 add a,a ; a := code*2 066B: EB ex hl,de 066C: 217906 ld hl,pc_jumpblock 066F: 85 add l 0670: 6F ld l,a 0671: 3001 jr nc,$+3 0673: 24 inc h 0674: 7E ld a,(hl) 0675: 23 inc hl 0676: 66 ld h,(hl) 0677: 6F ld l,a 0678: E9 jp (hl) 0679: 0679: ; Jumpblock für Controlcodes [0 .. 31] 0679: ; in: Printposition in dec (nicht hlc) 0679: ; out: Printposition in hlc 0679: pc_jumpblock: 0679: B906 defw pc_eot ; $00 End of text 067B: 1507 defw pc_home ; $01 Locate 0,0 067D: 0F07 defw pc_cls ; $02 Clear screen & home cursor 067F: 3907 defw pc_locate ; $03 Arguments: row,col 0681: 4207 defw pc_setcol ; $04 Argument: col [0..255] 0683: 4707 defw pc_setrow ; $05 Argument: row [0..23] ((größere Werte scrollen Screen)) 0685: 5707 defw pc_setattr ; $06 Argument: pen_ink+paper_ink+bright+flashing 0687: 2F07 defw pc_setpen ; $07 Argument: pen color black ... white 0689: 3407 defw pc_setpaper ; $08 Argument: paper color black_paper ... white_paper 068B: 4C07 defw pc_clrcols ; $09 Argument: pixel columns [0..255] (0=256) 068D: 1F07 defw pc_tab ; $0A 068F: B906B906 defw pc_11,pc_12 0693: 2307 defw pc_newline ; $0D 0695: D706DE06 defw pc_inverse_off,pc_inverse_on 0699: E506EC06 defw pc_narrow_off, pc_narrow_on 069D: F306FA06 defw pc_bold_off, pc_bold_on 06A1: 08070107 defw pc_log_on, pc_log_off 06A5: BB06C206 defw pc_flash_off, pc_flash_on 06A9: C906D006 defw pc_bright_off, pc_bright_on 06AD: 5107 defw pc_clr2eol 06AF: B906B906 06B3: B906B906 06B7: B906 defw pc_27,pc_28,pc_29,pc_30,pc_31 06B9: 06B9: 06B9: ; unknown ctrl codes: 06B9: pc_11: 06B9: pc_12: 06B9: pc_27: 06B9: pc_28: 06B9: pc_29: 06B9: pc_30: 06B9: pc_31: 06B9: ;di ; debug 06B9: ;halt 06B9: ;jr pc_eot 06B9: 06B9: ; end of text: char(0) 06B9: ; sollte eigentlich nicht vorkommen 06B9: pc_eot: 06B9: EB ex hl,de 06BA: C9 ret 06BB: 06BB: pc_flash_off: 06BB: 210F5B ld hl,print_attr 06BE: CBBE res 7,(hl) 06C0: EB ex hl,de 06C1: C9 ret 06C2: 06C2: pc_flash_on: 06C2: 210F5B ld hl,print_attr 06C5: CBFE set 7,(hl) 06C7: EB ex hl,de 06C8: C9 ret 06C9: 06C9: pc_bright_off: 06C9: 210F5B ld hl,print_attr 06CC: CBB6 res 6,(hl) 06CE: EB ex hl,de 06CF: C9 ret 06D0: 06D0: pc_bright_on: 06D0: 210F5B ld hl,print_attr 06D3: CBF6 set 6,(hl) 06D5: EB ex hl,de 06D6: C9 ret 06D7: 06D7: pc_inverse_off: 06D7: 21105B ld hl,print_flags 06DA: CB8E res pbit_inverse,(hl) 06DC: EB ex hl,de 06DD: C9 ret 06DE: 06DE: pc_inverse_on: 06DE: 21105B ld hl,print_flags 06E1: CBCE set pbit_inverse,(hl) 06E3: EB ex hl,de 06E4: C9 ret 06E5: 06E5: pc_narrow_off: 06E5: 21105B ld hl,print_flags 06E8: CB86 res pbit_narrow,(hl) 06EA: EB ex hl,de 06EB: C9 ret 06EC: 06EC: pc_narrow_on: 06EC: 21105B ld hl,print_flags 06EF: CBC6 set pbit_narrow,(hl) 06F1: EB ex hl,de 06F2: C9 ret 06F3: 06F3: pc_bold_off: 06F3: 21105B ld hl,print_flags 06F6: CB96 res pbit_bold,(hl) 06F8: EB ex hl,de 06F9: C9 ret 06FA: 06FA: pc_bold_on: 06FA: 21105B ld hl,print_flags 06FD: CBD6 set pbit_bold,(hl) 06FF: EB ex hl,de 0700: C9 ret 0701: 0701: pc_log_off: 0701: 21105B ld hl,print_flags 0704: CB9E res pbit_log,(hl) 0706: EB ex hl,de 0707: C9 ret 0708: 0708: pc_log_on: 0708: 21105B ld hl,print_flags 070B: CBDE set pbit_log,(hl) 070D: EB ex hl,de 070E: C9 ret 070F: 070F: ; cls, set border, home cursor, reset scroll count 070F: pc_cls: 070F: 3A0F5B ld a,(print_attr) 0712: CD7D0C call clear_screen_with_attr_no_exx ; clear screen with current attr 0715: ;jr pc_home 0715: 0715: ; home cursor, reset scroll count 0715: pc_home: 0715: 97 sub a ; reset "Scroll?" message count down 0716: 32115B ld (print_scrollcount),a 0719: 0E80 ld c,$80 071B: 210040 ld hl,$4000 071E: C9 ret 071F: 071F: ; tab => alle 4 Byte (etwa 6 Buchstaben) 071F: ; TODO: Attribute setzen? 071F: pc_tab: 071F: 3E03 ld a,3 ; mask 0721: 1802 jr pc_nl 0723: 0723: pc_newline: 0723: 3E1F ld a,$1f ; mask 0725: 0E80 pc_nl ld c,$80 0727: EB ex hl,de ; hl := screenbyte addr 0728: B5 or l 0729: 3C inc a 072A: 6F ld l,a 072B: C0 ret nz ; kein Übertrag über Blockgrenze (Zeilengrenze egal!) 072C: C35A06 jp pc_e ; nächster Block, evtl. Screenende => scrollen 072F: 072F: pc_setpen: ; Argument: pen color black ... white 072F: 216807 ld hl,pc_setpen_resume 0732: 1826 jr pc_argx 0734: 0734: pc_setpaper: ; Argument: paper color black ... white 0734: 216F07 ld hl,pc_setpaper_resume 0737: 1821 jr pc_argx 0739: 0739: pc_locate: ; Arguments: row [-128.. [0..23] ..127], col [0..255] 0739: 213E07 ld hl,pc_locate_resume 073C: 181C jr pc_argx 073E: 073E: pc_locate_resume: 073E: CD8E07 call pc_setrow_resume 0741: EB ex hl,de 0742: ;jr pc_setcol 0742: 0742: pc_setcol: ; Argument: col [0..255] 0742: 218407 ld hl,pc_setcol_resume 0745: 1813 jr pc_argx 0747: 0747: pc_setrow: ; Argument: row [0..23] bzw. [-128 .. +127] may scroll 0747: 218E07 ld hl,pc_setrow_resume 074A: 180E jr pc_argx 074C: 074C: pc_clrcols: ; Argument: columns [0..255] (0=256) 074C: 216407 ld hl,pc_clrcols_resume 074F: 1809 jr pc_argx 0751: 0751: pc_clr2eol: 0751: 0600 ld b,0 ; b = cols = 0 = 256; will be truncated 0753: EB ex hl,de ; hl -> pixel 0754: C3D707 jp print_clear_cols_no_exx 0757: 0757: pc_setattr: ; Argument: attribute %FBPapPen (Flash, Bright, Paper, Pen) 0757: 217F07 ld hl,pc_setattr_resume 075A: ;jr pc_argx 075A: 075A: 22145B pc_argx ld (print_pending_ctl),hl 075D: 21105B ld hl,print_flags 0760: CBE6 set pbit_pending_ctl,(hl) 0762: EB ex hl,de 0763: C9 ret 0764: 0764: pc_clrcols_resume: 0764: 47 ld b,a ; b = cols 0765: EB ex hl,de ; hl -> pixel 0766: 186F jr print_clear_cols_no_exx 0768: 0768: pc_setpen_resume: 0768: E607 and a,$07 ; force legal 076A: 47 ld b,a ; b := new val. 076B: 3EF8 ld a,$F8 ; other bits mask 076D: 1808 jr pc_sp_r 076F: 076F: pc_setpaper_resume: 076F: 07 rlca 0770: 07 rlca 0771: 07 rlca 0772: E638 and a,$38 ; force legal 0774: 47 ld b,a ; b := new val. 0775: 3EC7 ld a,$C7 ; other bits mask 0777: 210F5B pc_sp_r ld hl,print_attr 077A: A6 and a,(hl) ; a := other bits 077B: B0 or b ; a := new attr 077C: 77 ld (hl),a ; store new attr 077D: EB ex hl,de 077E: C9 ret 077F: 077F: pc_setattr_resume: 077F: 320F5B ld (print_attr),a ; store new attr 0782: EB ex hl,de 0783: C9 ret 0784: 0784: pc_setcol_resume: 0784: EB ex hl,de ; => wieder hlc 0785: F5 push af ; new col [0..255] 0786: CD3B08 call calc_row_b_col_c_from_hlc 0789: F1 pop af 078A: 4F ld c,a ; new col 078B: C37308 jp calc_hlc_from_row_b_col_c 078E: 078E: pc_setrow_resume: 078E: EB ex hl,de 078F: FE18 cp a,24 ; force legal (TODO: evtl. scroll up/down) 0791: 3806 jr c,pc_sr1 ; [0 .. a .. 23] 0793: 87 add a ; mi -> cy 0794: 3E17 ld a,23 0796: 3001 jr nc,$+3 ; a>23 => a:=23 0798: 97 sub a ; a<0 => a:= 0 0799: 0799: F5 pc_sr1 push af 079A: CD3B08 call calc_row_b_col_c_from_hlc 079D: 97 sub a 079E: 32115B ld (print_scrollcount),a ; reset scroll count 07A1: F1 pop af 07A2: 47 ld b,a 07A3: C37308 jp calc_hlc_from_row_b_col_c 07A6: 07A6: 07A6: 07A6: ; ------------------------------------------------------------ 07A6: ; Clear current row with current paper color 07A6: ; 07A6: ; Does not move the text cursor 07A6: ; 07A6: ; in: -- 07A6: ; out: -- 07A6: ; mod: af 07A6: 07A6: print_clear_current_row: 07A6: D7 rst save_registers 07A7: 2A0C5B ld hl,(print_hl) 07AA: 1809 jr print_clear_row_hl_quick 07AC: 07AC: 07AC: 07AC: ; ------------------------------------------------------------ 07AC: ; Clear text row with current paper color 07AC: ; 07AC: ; in: b = row 07AC: ; out: -- 07AC: ; mod: af 07AC: 07AC: print_clear_row: 07AC: D7 rst save_registers 07AD: 0E00 ld c,0 07AF: CD7308 call calc_hlc_from_row_b_col_c 07B2: 1809 jr pcr_hl 07B4: 07B4: 07B4: 07B4: ; ------------------------------------------------------------ 07B4: ; Clear text row with current paper color 07B4: ; 07B4: ; in: hl -> current pixel byte 07B4: ; out: -- 07B4: ; mod: af 07B4: 07B4: print_clear_row_hl: 07B4: D7 rst save_registers 07B5: 07B5: print_clear_row_hl_quick: 07B5: 7C ld a,h ; hl -> top row of pixels 07B6: E6F8 and $f8 07B8: 67 ld h,a 07B9: 07B9: 7D ld a,l ; hl -> column 0 07BA: E6E0 and $e0 07BC: 6F ld l,a 07BD: 07BD: 012001 pcr_hl ld bc, 1*256 + 32 ; 1 row, 32 cells 07C0: 3A0F5B ld a,(print_attr) 07C3: C39C0C jp clear_cbox_with_attr_quick 07C6: 07C6: 07C6: 07C6: ; ------------------------------------------------------------ 07C6: ; Clear range of text row 07C6: ; 07C6: ; Lösche B Pixelspalten ab hlc mit dem aktuellen print_attr. 07C6: ; Löscht maximal bis Zeilenende 07C6: ; Wenn B=0 wird B=256 angenommen. 07C6: ; 07C6: ; in: hl -> current pixel byte 07C6: ; c = current pixel mask 07C6: ; b = width; 0=256 07C6: ; out: -- 07C6: ; mod: af 07C6: 07C6: v_clear_cols: ; opcode v_clear_cols -- 07C6: 7B ld a,e ; a=cols 07C7: D1 pop de ; de = new top value 07C8: C5 push bc 07C9: 47 ld b,a ; b=cols 07CA: 2A0C5B ld hl,(print_hl) 07CD: 3A0E5B ld a,(print_c) 07D0: 4F ld c,a 07D1: CDD707 call print_clear_cols 07D4: C32000 jp vip ; pop bc; ld iy,vip_dis; jp (iy) 07D7: 07D7: 07D7: print_clear_cols_no_exx: 07D7: print_clear_cols: 07D7: D7 rst save_registers 07D8: 07D8: ; validate width: must not extend beyond end of line 07D8: 5950 ld de,bc ; retten 07DA: CD3B08 call calc_row_b_col_c_from_hlc 07DD: 7A ld a,d ; width 07DE: A7 and a ; width = 0 = 256 ? 07DF: 2803 jr z,pcc1 ; ja => truncate 07E1: 81 add c ; current col + width 07E2: 3003 jr nc,pcc2 ; ok 07E4: 07E4: ; truncate b to end of line: 07E4: AF pcc1 xor a 07E5: 91 sub c 07E6: 57 ld d,a ; d = width (truncated) 07E7: 4B42 pcc2 ld bc,de ; b = width; c = pixel mask (again) 07E9: 07E9: ; print preceeding columns: 07E9: ; wir drucken auch die ersten vollen 8 pixelspalten mit up_clear_partial_cell, 07E9: ; weil dadurch B, falls es 0 für 256 war, unter $100 erniedrigt wird. 07E9: ; das erspart das Geteste und Verzweigen für B=0. 07E9: ;bit 7,c ; start at start of cell? 07E9: ;jr nz,pcb1 ; yes 07E9: 07E9: CD0B08 call up_clear_partial_cell 07EC: 78 ld a,b 07ED: A7 and a 07EE: C8 ret z ; 0 pixels remaining 07EF: 2C inc l ; hl -> next pixel byte 07F0: 07F0: ; clear complete cells: 07F0: 50 pcb1 ld d,b ; d = b: count retten 07F1: 78 ld a,b 07F2: 0F rrca 07F3: 0F rrca 07F4: 0F rrca 07F5: E61F and $1f 07F7: 5F ld e,a ; cell count retten 07F8: 07F8: 4F ld c,a ; c = cells 07F9: 0601 ld b,1 ; b = rows 07FB: 3A0F5B ld a,(print_attr) ; a = attr 07FE: C49B0C call nz,clear_cbox_with_attr_no_exx 0801: 0801: 7D ld a,l 0802: 83 add e 0803: 6F ld l,a ; hl += cells 0804: 0E80 ld c,$80 ; c = pixel mask 0806: 0806: ; clear remaining pixels right: 0806: 7A ld a,d ; a = count 0807: E607 and 7 0809: C8 ret z ; no trailing partial block 080A: 080A: 47 ld b,a 080B: ;jr up_clear_partial_cell 080B: 080B: 080B: 080B: ; --------------------------------------- 080B: ; clear partial cell with mask: 080B: ; 080B: ; in: hl -> top pixel row 080B: ; c = current pixel mask 080B: ; b = count >= 1 080B: ; out: c updated 080B: ; b decremented by number of pixel columns cleared 080B: ; hl not updated! 080B: ; mod: af, bc, hl 080B: 080B: up_clear_partial_cell: 080B: AF xor a 080C: 3805 pcb3 jr c,pcb2 ; end of character cell reached 080E: B1 or c 080F: CB09 rrc c 0811: 10F9 djnz pcb3 0813: 0813: ; a = mask 0813: 0813: C5 pcb2 push bc 0814: E5 push hl 0815: 0815: 2F cpl 0816: 4F ld c,a ; mask 0817: 0817: 7C ld a,h ; hl -> top row of pixels 0818: E6F8 and $f8 081A: 67 ld h,a 081B: 081B: 0608 ld b,8 081D: 7E pcb4 ld a,(hl) 081E: A1 and c 081F: 77 ld (hl),a 0820: 24 inc h 0821: 10FA djnz pcb4 0823: 25 dec h ; hl back into cell, bottom row 0824: 0824: CD270E call calc_attr_hl_for_pixel_hl 0827: 3A0F5B ld a,(print_attr) 082A: 77 ld (hl),a 082B: 082B: E1 pop hl 082C: C1 pop bc 082D: C9 ret 082E: 082E: 082E: 082E: ; ------------------------------------------------------------ 082E: ; Get Textcursor Row and Column 082E: ; 082E: ; in: -- 082E: ; out: B = row [0..23] 082E: ; C = col [0..255] 082E: ; mod: af, bc 082E: 082E: print_get_row_b_and_col_c: 082E: E5 push hl 082F: 210E5B ld hl,print_c 0832: 4E ld c,(hl) 0833: 2A0C5B ld hl,(print_hl) 0836: CD3B08 call calc_row_b_col_c_from_hlc 0839: E1 pop hl 083A: C9 ret 083B: 083B: 083B: 083B: ; ------------------------------------------------------------ 083B: ; UP: Berechne Row B und Col C 083B: ; zu Byteadresse HL und Bitmaske C 083B: ; 083B: ; in: HL = Byteadresse [$4000..$57FF] 083B: ; C = Bitmaske 083B: ; out: B = row [0..23] 083B: ; C = col [0..255] 083B: ; A = B 083B: ; mod: AF, BC 083B: 083B: calc_row_b_col_c_from_hlc: 083B: 083B: ; konvertiere pixelmaske in c in spaltenzahl 0 (ganz links) ... 7 (ganz rechts) 083B: ; Diese Routine braucht im Mittel 78.0 Taktzyklen. 083B: ; Eine Schleife mit rlca/inc r/jr nz bräuchte im Mittel etwa 100 Takte. 083B: 083B: 3E0F ld a,$0F ; Maske: ____XXXX hier dabei? => col+4 083D: A1 and c 083E: 47 ld b,a ; b := 0 wenn a=0 083F: 2802 jr z,$+4 0841: 0604 ld b,4 ; b := 4 wenn a!=0 0843: 0843: 3E33 ld a,$33 ; Maske: __XX__XX hier dabei? => col+2 0845: A1 and c 0846: 2802 jr z,$+4 0848: CBC8 set 1,b 084A: 084A: 3E55 ld a,$55 ; Maske: _X_X_X_X hier dabei? => col+1 084C: A1 and c 084D: 2801 jr z,$+3 084F: 04 inc b 0850: 48 ld c,b ; c = %00000bbb = col inside char [0..7] 0851: 0851: ; l = %rrrccccc wobei rrr = row inside char und ccccc = char col 0851: ; l rotieren, dass es so aussieht: 0851: ; l = %cccccrrr damit stehen rrr und ccccc auf den positionen, 0851: ; die ihrer Wertigkeit entspricht 0851: 0851: 7D ld a,l 0852: 07 rlca 0853: 07 rlca 0854: 07 rlca 0855: 47 ld b,a ; b = a = %cccccrrr 0856: 0856: E6F8 and $F8 ; a = %ccccc000 0858: B1 or c ; a = %cccccbbb 0859: 4F ld c,a ; c = pixelspalte = fertig 085A: 085A: 78 ld a,b 085B: E607 and 7 085D: 47 ld b,a ; b = %00000rrr 085E: 085E: ; h = %010bbzzz wobei bb = 8-Textzeilen-Block und zzz = pixelzeile innerhalb eines Zeichens 085E: 085E: 7C ld a,h 085F: E618 and $18 ; a = %000bb000 0861: B0 or b ; a = %000bbrrr 0862: 47 ld b,a ; b = character row = fertig 0863: 0863: C9 ret 0864: 0864: 0864: 0864: ; ------------------------------------------------------------ 0864: ; Set Textcursor Row & Column 0864: ; 0864: ; in: B = row [0..23] 0864: ; C = col [0..255] 0864: ; out: -- 0864: ; mod: af 0864: 0864: print_set_row_b_and_col_c: 0864: E5 push hl 0865: C5 push bc 0866: CD7308 call calc_hlc_from_row_b_col_c 0869: 220C5B ld (print_hl),hl 086C: 210E5B ld hl,print_c 086F: 71 ld (hl),c 0870: C1 pop bc 0871: E1 pop hl 0872: C9 ret 0873: 0873: 0873: 0873: ; ------------------------------------------------------------ 0873: ; UP: Berechne Byteadresse HL und Bitmaske C 0873: ; zu Row B [0..23] und Col C [0..255] 0873: ; 0873: ; in: B = row [0..23] 0873: ; C = col [0..255] 0873: ; out: HL = Byteadresse [$4000..[$5800 0873: ; C = Bitmaske 0873: ; A = C 0873: ; mod: AF, BC, HL 0873: 0873: calc_hlc_from_row_b_col_c: 0873: 0873: ; hl := %010bb000.rrrccccc bb=block, rr=row inside block, ccccc=char col 0873: ; c = %10000000 >> (c&7) 0873: 0873: 78 ld a,b 0874: E618 and $18 ; a = %000bb000 0876: F640 or $40 0878: 67 ld h,a ; h = %010bb000 = fertig 0879: 0879: 78 ld a,b 087A: E607 and 7 087C: 47 ld b,a ; b = %00000rrr 087D: 087D: 79 ld a,c 087E: E6F8 and $F8 ; a = %ccccc000 0880: B0 or b ; a = %cccccrrr 0881: 0F rrca 0882: 0F rrca 0883: 0F rrca ; a = %rrrccccc 0884: 6F ld l,a ; l = %rrrccccc = fertig 0885: 0885: 79 ld a,c ; a = pixel col 0886: E607 and 7 ; a = pixel col inside byte 0888: C690 add pmasks%256 088A: 4F ld c,a 088B: 0608 ld b,pmasks/256 088D: 0A ld a,(bc) 088E: 4F ld c,a 088F: 088F: C9 ret 0890: 0890: #if $/256 != ($+8-1)/256 0890: defs 256 - $%256 0890: #endif 0890: 0890: 80402010 0894: 08040201 pmasks defb $80, $40, $20, $10, $08, $04, $02, $01 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: 0898: #include "print.ass" 0898: 0898: 0898: ; ------------------------------------------------------------ 0898: ; Calc address of character image in charset table 0898: ; 0898: ; Note: The character code is not checked. 0898: ; Garbage in => garbage out. 0898: ; But one could extend the glyph table with code positions $00 .. $1F. 0898: ; Then the character code to access these glyphs would be 0898: ; $00 .. $1F or equivalent $80 .. $9F. 0898: ; 0898: ; in: A = char [33..127] 0898: ; out: HL -> glyph 0898: ; mod: AF, HL 0898: 0898: calc_glyph_address: 0898: 87 add a,a ; *2 0899: 21750A ld hl,charset_ptr -2*33 ; hl -> glyph pointer table 089C: 85 add a,l 089D: 6F ld l,a 089E: 3001 jr nc,$+3 08A0: 24 inc h 08A1: 08A1: 7E ld a,(hl) 08A2: 23 inc hl 08A3: 66 ld h,(hl) 08A4: 6F ld l,a ; hl -> glyph 08A5: C9 ret 08A6: 08A6: 08A6: 08A6: ; ------------------------------------------------------------ 08A6: ; Character set 08A6: ; starting with char 33 08A6: ; first byte of each glyph is marked with bit 0 set 08A6: 08A6: 08A6: charcode_icursor equ 128+20 08A6: FF c20 defb %11111110 | 1 08A7: 08A7: charcode_io equ 128+21 08A7: 11 c21 defb %00010000 | 1 08A8: 28 defb %00101000 08A9: 44 defb %01000100 08AA: 44 defb %01000100 08AB: 44 defb %01000100 08AC: 44 defb %01000100 08AD: 28 defb %00101000 08AE: 10 defb %00010000 08AF: 08AF: charcode_gnd equ 128+22 08AF: 39 c22 defb %00111000 | 1 08B0: 44 defb %01000100 08B1: 92 defb %10010010 08B2: 92 defb %10010010 08B3: 92 defb %10010010 08B4: 44 defb %01000100 08B5: 38 defb %00111000 08B6: 08B6: charcode_vcc equ 128+23 08B6: 39 c23 defb %00111000 | 1 08B7: 44 defb %01000100 08B8: 92 defb %10010010 08B9: BA defb %10111010 08BA: 92 defb %10010010 08BB: 44 defb %01000100 08BC: 38 defb %00111000 08BD: 08BD: charcode_3state equ 128+24 08BD: 07 c24 defb %00000110 | 1 08BE: 1A defb %00011010 08BF: 62 defb %01100010 08C0: 1A defb %00011010 08C1: 06 defb %00000110 08C2: 08C2: charcode_oK equ 128 +25 08C2: 49 c25 defb %01001000 | 1 08C3: 54 defb %01010100 08C4: 62 defb %01100010 08C5: 54 defb %01010100 08C6: 48 defb %01001000 08C7: 08C7: charcode_i_left equ 128 +26 08C7: charcode_o_right equ 128 +26 08C7: 7D c26 defb %01111100 | 1 08C8: 44 defb %01000100 08C9: 44 defb %01000100 08CA: 44 defb %01000100 08CB: 28 defb %00101000 08CC: 10 defb %00010000 08CD: 08CD: charcode_o_left equ 128 +27 08CD: charcode_i_right equ 128 +27 08CD: 11 c27 defb %00010000 | 1 08CE: 28 defb %00101000 08CF: 44 defb %01000100 08D0: 44 defb %01000100 08D1: 44 defb %01000100 08D2: 7C defb %01111100 08D3: 08D3: charcode_left_arrow equ 128 +28 08D3: 11 c28 defb %00010000 | 1 08D4: 38 defb %00111000 08D5: 7C defb %01111100 08D6: FE defb %11111110 08D7: 38 defb %00111000 08D8: 38 defb %00111000 08D9: 08D9: charcode_down_arrow equ 128 +29 08D9: 11 c29 defb %00010000 | 1 08DA: 30 defb %00110000 08DB: 7C defb %01111100 08DC: FC defb %11111100 08DD: 7C defb %01111100 08DE: 30 defb %00110000 08DF: 10 defb %00010000 08E0: 08E0: charcode_up_arrow equ 128 +30 08E0: 11 c30 defb %00010000 | 1 08E1: 18 defb %00011000 08E2: 7C defb %01111100 08E3: 7E defb %01111110 08E4: 7C defb %01111100 08E5: 18 defb %00011000 08E6: 10 defb %00010000 08E7: 08E7: charcode_right_arrow equ 128 +31 08E7: 39 c31 defb %00111000 | 1 08E8: 38 defb %00111000 08E9: FE defb %11111110 08EA: 7C defb %01111100 08EB: 38 defb %00111000 08EC: 10 defb %00010000 08ED: 08ED: 01 c32 defb %00000000 | 1 ; space 08EE: 00 defb %00000000 08EF: 08EF: charset: 08EF: 5F c33 defb %01011110 | 1 ; ! 08F0: 08F0: 07 c34 defb %00000110 | 1 ; " 08F1: 00 defb %00000000 08F2: 06 defb %00000110 08F3: 08F3: 25 c35 defb %00100100 | 1 ; # 08F4: 7E defb %01111110 08F5: 24 defb %00100100 08F6: 24 defb %00100100 08F7: 7E defb %01111110 08F8: 24 defb %00100100 08F9: 08F9: 5D c36 defb %01011100 | 1 ; $ 08FA: 54 defb %01010100 08FB: FE defb %11111110 08FC: 54 defb %01010100 08FD: 74 defb %01110100 08FE: 08FE: 47 c37 defb %01000110 | 1 ; % 08FF: 26 defb %00100110 0900: 10 defb %00010000 0901: 08 defb %00001000 0902: 64 defb %01100100 0903: 62 defb %01100010 0904: 0904: 21 c38 defb %00100000 | 1 ; & 0905: 54 defb %01010100 0906: 4A defb %01001010 0907: 54 defb %01010100 0908: 20 defb %00100000 0909: 50 defb %01010000 090A: 090A: 07 c39 defb %00000110 | 1 ; ' 090B: 090B: 3D c40 defb %00111100 | 1 ; ( 090C: 42 defb %01000010 090D: 090D: 43 c41 defb %01000010 | 1 ; ) 090E: 3C defb %00111100 090F: 090F: 11 c42 defb %00010000 | 1 ; * 0910: 54 defb %01010100 0911: 38 defb %00111000 0912: 54 defb %01010100 0913: 10 defb %00010000 0914: 0914: 11 c43 defb %00010000 | 1 ; + 0915: 10 defb %00010000 0916: 7C defb %01111100 0917: 10 defb %00010000 0918: 10 defb %00010000 0919: 0919: 81 c44 defb %10000000 | 1 ; , 091A: 60 defb %01100000 091B: 091B: 11 c45 defb %00010000 | 1 ; - 091C: 10 defb %00010000 091D: 10 defb %00010000 091E: 10 defb %00010000 091F: 10 defb %00010000 0920: 0920: 61 c46 defb %01100000 | 1 ; . 0921: 60 defb %01100000 0922: 0922: 41 c47 defb %01000000 | 1 ; / 0923: 20 defb %00100000 0924: 10 defb %00010000 0925: 08 defb %00001000 0926: 04 defb %00000100 0927: 0927: 3D c48 defb %00111100 | 1 ; 0 0928: 62 defb %01100010 0929: 5A defb %01011010 092A: 46 defb %01000110 092B: 3C defb %00111100 092C: 092C: 45 c49 defb %01000100 | 1 ; 1 092D: 42 defb %01000010 092E: 7E defb %01111110 092F: 40 defb %01000000 0930: 40 defb %01000000 0931: 0931: 65 c50 defb %01100100 | 1 ; 2 0932: 52 defb %01010010 0933: 52 defb %01010010 0934: 52 defb %01010010 0935: 4C defb %01001100 0936: 0936: 25 c51 defb %00100100 | 1 ; 3 0937: 42 defb %01000010 0938: 4A defb %01001010 0939: 4A defb %01001010 093A: 34 defb %00110100 093B: 093B: 31 c52 defb %00110000 | 1 ; 4 093C: 28 defb %00101000 093D: 24 defb %00100100 093E: 7E defb %01111110 093F: 20 defb %00100000 0940: 0940: 2F c53 defb %00101110 | 1 ; 5 0941: 4A defb %01001010 0942: 4A defb %01001010 0943: 4A defb %01001010 0944: 32 defb %00110010 0945: 0945: 3D c54 defb %00111100 | 1 ; 6 0946: 4A defb %01001010 0947: 4A defb %01001010 0948: 4A defb %01001010 0949: 30 defb %00110000 094A: 094A: 03 c55 defb %00000010 | 1 ; 7 094B: 02 defb %00000010 094C: 72 defb %01110010 094D: 0A defb %00001010 094E: 06 defb %00000110 094F: 094F: 35 c56 defb %00110100 | 1 ; 8 0950: 4A defb %01001010 0951: 4A defb %01001010 0952: 4A defb %01001010 0953: 34 defb %00110100 0954: 0954: 0D c57 defb %00001100 | 1 ; 9 0955: 52 defb %01010010 0956: 52 defb %01010010 0957: 52 defb %01010010 0958: 3C defb %00111100 0959: 0959: 49 c58 defb %01001000 | 1 ; : 095A: 095A: 81 c59 defb %10000000 | 1 ; ; 095B: 64 defb %01100100 095C: 095C: 11 c60 defb %00010000 | 1 ; < 095D: 28 defb %00101000 095E: 44 defb %01000100 095F: 095F: 29 c61 defb %00101000 | 1 ; = 0960: 28 defb %00101000 0961: 28 defb %00101000 0962: 28 defb %00101000 0963: 0963: 45 c62 defb %01000100 | 1 ; > 0964: 28 defb %00101000 0965: 10 defb %00010000 0966: 0966: 05 c63 defb %00000100 | 1 ; ? 0967: 02 defb %00000010 0968: 52 defb %01010010 0969: 0A defb %00001010 096A: 04 defb %00000100 096B: 096B: 3D c64 defb %00111100 | 1 ; @ 096C: 42 defb %01000010 096D: 5A defb %01011010 096E: 56 defb %01010110 096F: 5A defb %01011010 0970: 1C defb %00011100 0971: 0971: 7D c65 defb %01111100 | 1 ; A 0972: 12 defb %00010010 0973: 12 defb %00010010 0974: 12 defb %00010010 0975: 7C defb %01111100 0976: 0976: 7F c66 defb %01111110 | 1 ; B 0977: 4A defb %01001010 0978: 4A defb %01001010 0979: 4A defb %01001010 097A: 34 defb %00110100 097B: 097B: 3D c67 defb %00111100 | 1 ; C 097C: 42 defb %01000010 097D: 42 defb %01000010 097E: 42 defb %01000010 097F: 24 defb %00100100 0980: 0980: 7F c68 defb %01111110 | 1 ; D 0981: 42 defb %01000010 0982: 42 defb %01000010 0983: 42 defb %01000010 0984: 3C defb %00111100 0985: 0985: 7F c69 defb %01111110 | 1 ; E 0986: 4A defb %01001010 0987: 4A defb %01001010 0988: 4A defb %01001010 0989: 42 defb %01000010 098A: 098A: 7F c70 defb %01111110 | 1 ; F 098B: 0A defb %00001010 098C: 0A defb %00001010 098D: 0A defb %00001010 098E: 02 defb %00000010 098F: 098F: 3D c71 defb %00111100 | 1 ; G 0990: 42 defb %01000010 0991: 52 defb %01010010 0992: 52 defb %01010010 0993: 34 defb %00110100 0994: 0994: 7F c72 defb %01111110 | 1 ; H 0995: 08 defb %00001000 0996: 08 defb %00001000 0997: 08 defb %00001000 0998: 7E defb %01111110 0999: 0999: 43 c73 defb %01000010 | 1 ; I 099A: 7E defb %01111110 099B: 42 defb %01000010 099C: 099C: 31 c74 defb %00110000 | 1 ; J 099D: 40 defb %01000000 099E: 40 defb %01000000 099F: 3E defb %00111110 09A0: 09A0: 7F c75 defb %01111110 | 1 ; K 09A1: 18 defb %00011000 09A2: 18 defb %00011000 09A3: 24 defb %00100100 09A4: 42 defb %01000010 09A5: 09A5: 7F c76 defb %01111110 | 1 ; L 09A6: 40 defb %01000000 09A7: 40 defb %01000000 09A8: 40 defb %01000000 09A9: 09A9: 7F c77 defb %01111110 | 1 ; M 09AA: 04 defb %00000100 09AB: 08 defb %00001000 09AC: 08 defb %00001000 09AD: 04 defb %00000100 09AE: 7E defb %01111110 09AF: 09AF: 7F c78 defb %01111110 | 1 ; N 09B0: 04 defb %00000100 09B1: 08 defb %00001000 09B2: 10 defb %00010000 09B3: 20 defb %00100000 09B4: 7E defb %01111110 09B5: 09B5: 3D c79 defb %00111100 | 1 ; O 09B6: 42 defb %01000010 09B7: 42 defb %01000010 09B8: 42 defb %01000010 09B9: 42 defb %01000010 09BA: 3C defb %00111100 09BB: 09BB: 7F c80 defb %01111110 | 1 ; P 09BC: 12 defb %00010010 09BD: 12 defb %00010010 09BE: 12 defb %00010010 09BF: 0C defb %00001100 09C0: 09C0: 3D c81 defb %00111100 | 1 ; Q 09C1: 42 defb %01000010 09C2: 52 defb %01010010 09C3: 62 defb %01100010 09C4: 42 defb %01000010 09C5: 3C defb %00111100 09C6: 09C6: 7F c82 defb %01111110 | 1 ; R 09C7: 12 defb %00010010 09C8: 12 defb %00010010 09C9: 32 defb %00110010 09CA: 4C defb %01001100 09CB: 09CB: 25 c83 defb %00100100 | 1 ; S 09CC: 4A defb %01001010 09CD: 4A defb %01001010 09CE: 4A defb %01001010 09CF: 30 defb %00110000 09D0: 09D0: 03 c84 defb %00000010 | 1 ; T 09D1: 02 defb %00000010 09D2: 7E defb %01111110 09D3: 02 defb %00000010 09D4: 02 defb %00000010 09D5: 09D5: 3F c85 defb %00111110 | 1 ; U 09D6: 40 defb %01000000 09D7: 40 defb %01000000 09D8: 40 defb %01000000 09D9: 3E defb %00111110 09DA: 09DA: 1F c86 defb %00011110 | 1 ; V 09DB: 20 defb %00100000 09DC: 40 defb %01000000 09DD: 20 defb %00100000 09DE: 1E defb %00011110 09DF: 09DF: 3F c87 defb %00111110 | 1 ; W 09E0: 40 defb %01000000 09E1: 20 defb %00100000 09E2: 20 defb %00100000 09E3: 40 defb %01000000 09E4: 3E defb %00111110 09E5: 09E5: 43 c88 defb %01000010 | 1 ; X 09E6: 24 defb %00100100 09E7: 18 defb %00011000 09E8: 18 defb %00011000 09E9: 24 defb %00100100 09EA: 42 defb %01000010 09EB: 09EB: 07 c89 defb %00000110 | 1 ; Y 09EC: 08 defb %00001000 09ED: 70 defb %01110000 09EE: 08 defb %00001000 09EF: 06 defb %00000110 09F0: 09F0: 43 c90 defb %01000010 | 1 ; Z 09F1: 62 defb %01100010 09F2: 52 defb %01010010 09F3: 4A defb %01001010 09F4: 46 defb %01000110 09F5: 42 defb %01000010 09F6: 09F6: 7F c91 defb %01111110 | 1 ; [ 09F7: 42 defb %01000010 09F8: 42 defb %01000010 09F9: 09F9: 05 c92 defb %00000100 | 1 ; \ 09FA: 08 defb %00001000 09FB: 10 defb %00010000 09FC: 20 defb %00100000 09FD: 40 defb %01000000 09FE: 09FE: 43 c93 defb %01000010 | 1 ; ] 09FF: 42 defb %01000010 0A00: 7E defb %01111110 0A01: 0A01: 09 c94 defb %00001000 | 1 ; ^ (Pfeil hoch) 0A02: 04 defb %00000100 0A03: 7E defb %01111110 0A04: 04 defb %00000100 0A05: 08 defb %00001000 0A06: 0A06: 81 c95 defb %10000000 | 1 ; _ 0A07: 80 defb %10000000 0A08: 80 defb %10000000 0A09: 80 defb %10000000 0A0A: 0A0A: 49 c96 defb %01001000 | 1 ; £ 0A0B: 7C defb %01111100 0A0C: 4A defb %01001010 0A0D: 42 defb %01000010 0A0E: 44 defb %01000100 0A0F: 0A0F: 21 c97 defb %00100000 | 1 ; a 0A10: 54 defb %01010100 0A11: 54 defb %01010100 0A12: 54 defb %01010100 0A13: 78 defb %01111000 0A14: 0A14: 7F c98 defb %01111110 | 1 ; b 0A15: 48 defb %01001000 0A16: 48 defb %01001000 0A17: 48 defb %01001000 0A18: 30 defb %00110000 0A19: 0A19: 39 c99 defb %00111000 | 1 ; c 0A1A: 44 defb %01000100 0A1B: 44 defb %01000100 0A1C: 44 defb %01000100 0A1D: 0A1D: 31 c100 defb %00110000 | 1 ; d 0A1E: 48 defb %01001000 0A1F: 48 defb %01001000 0A20: 48 defb %01001000 0A21: 7E defb %01111110 0A22: 0A22: 39 c101 defb %00111000 | 1 ; e 0A23: 54 defb %01010100 0A24: 54 defb %01010100 0A25: 54 defb %01010100 0A26: 48 defb %01001000 0A27: 0A27: 7D c102 defb %01111100 | 1 ; f 0A28: 0A defb %00001010 0A29: 02 defb %00000010 0A2A: 0A2A: 19 c103 defb %00011000 | 1 ; g 0A2B: A4 defb %10100100 0A2C: A4 defb %10100100 0A2D: A4 defb %10100100 0A2E: 7C defb %01111100 0A2F: 0A2F: 7F c104 defb %01111110 | 1 ; h 0A30: 08 defb %00001000 0A31: 08 defb %00001000 0A32: 08 defb %00001000 0A33: 70 defb %01110000 0A34: 0A34: 49 c105 defb %01001000 | 1 ; i 0A35: 7A defb %01111010 0A36: 40 defb %01000000 0A37: 0A37: 41 c106 defb %01000000 | 1 ; j 0A38: 80 defb %10000000 0A39: 7A defb %01111010 0A3A: 00 defb %00000000 0A3B: 0A3B: 7F c107 defb %01111110 | 1 ; k 0A3C: 10 defb %00010000 0A3D: 28 defb %00101000 0A3E: 44 defb %01000100 0A3F: 0A3F: 3F c108 defb %00111110 | 1 ; l 0A40: 40 defb %01000000 0A41: 40 defb %01000000 0A42: 0A42: 7D c109 defb %01111100 | 1 ; m 0A43: 04 defb %00000100 0A44: 04 defb %00000100 0A45: 78 defb %01111000 0A46: 04 defb %00000100 0A47: 04 defb %00000100 0A48: 78 defb %01111000 0A49: 0A49: 7D c110 defb %01111100 | 1 ; n 0A4A: 04 defb %00000100 0A4B: 04 defb %00000100 0A4C: 04 defb %00000100 0A4D: 78 defb %01111000 0A4E: 0A4E: 39 c111 defb %00111000 | 1 ; o 0A4F: 44 defb %01000100 0A50: 44 defb %01000100 0A51: 44 defb %01000100 0A52: 38 defb %00111000 0A53: 0A53: FD c112 defb %11111100 | 1 ; p 0A54: 24 defb %00100100 0A55: 24 defb %00100100 0A56: 24 defb %00100100 0A57: 18 defb %00011000 0A58: 0A58: 19 c113 defb %00011000 | 1 ; q 0A59: 24 defb %00100100 0A5A: 24 defb %00100100 0A5B: 24 defb %00100100 0A5C: FC defb %11111100 0A5D: 0A5D: 79 c114 defb %01111000 | 1 ; r 0A5E: 04 defb %00000100 0A5F: 04 defb %00000100 0A60: 04 defb %00000100 0A61: 0A61: 49 c115 defb %01001000 | 1 ; s 0A62: 54 defb %01010100 0A63: 54 defb %01010100 0A64: 54 defb %01010100 0A65: 20 defb %00100000 0A66: 0A66: 05 c116 defb %00000100 | 1 ; t 0A67: 3E defb %00111110 0A68: 44 defb %01000100 0A69: 40 defb %01000000 0A6A: 0A6A: 3D c117 defb %00111100 | 1 ; u 0A6B: 40 defb %01000000 0A6C: 40 defb %01000000 0A6D: 40 defb %01000000 0A6E: 3C defb %00111100 0A6F: 0A6F: 0D c118 defb %00001100 | 1 ; v 0A70: 30 defb %00110000 0A71: 40 defb %01000000 0A72: 30 defb %00110000 0A73: 0C defb %00001100 0A74: 0A74: 3D c119 defb %00111100 | 1 ; w 0A75: 40 defb %01000000 0A76: 38 defb %00111000 0A77: 40 defb %01000000 0A78: 3C defb %00111100 0A79: 0A79: 45 c120 defb %01000100 | 1 ; x 0A7A: 28 defb %00101000 0A7B: 10 defb %00010000 0A7C: 28 defb %00101000 0A7D: 44 defb %01000100 0A7E: 0A7E: 1D c121 defb %00011100 | 1 ; y 0A7F: A0 defb %10100000 0A80: A0 defb %10100000 0A81: 7C defb %01111100 0A82: 0A82: 45 c122 defb %01000100 | 1 ; z 0A83: 64 defb %01100100 0A84: 54 defb %01010100 0A85: 4C defb %01001100 0A86: 44 defb %01000100 0A87: 0A87: 11 c123 defb %00010000 | 1 ; { 0A88: 7C defb %01111100 0A89: 82 defb %10000010 0A8A: 82 defb %10000010 0A8B: 0A8B: 7F c124 defb %01111110 | 1 ; | 0A8C: 0A8C: 83 c125 defb %10000010 | 1 ; } 0A8D: 82 defb %10000010 0A8E: 6C defb %01101100 0A8F: 10 defb %00010000 0A90: 0A90: 05 c126 defb %00000100 | 1 ; ~ 0A91: 02 defb %00000010 0A92: 04 defb %00000100 0A93: 02 defb %00000010 0A94: 0A94: 39 c127 defb %00111000 | 1 ; © (c) 0A95: 44 defb %01000100 0A96: 92 defb %10010010 0A97: AA defb %10101010 0A98: AA defb %10101010 0A99: 82 defb %10000010 0A9A: 44 defb %01000100 0A9B: 38 defb %00111000 0A9C: 0A9C: 01 c128 defb %00000000 | 1 ; stopper for last char 0A9D: 0A9D: 0A9D: ; 96 Pointer: char(33) .. char(127) + stopper 0A9D: 0A9D: A608A708 0AA1: AF08B608 0AA5: BD08C208 0AA9: C708CD08 0AAD: D308D908 defw c20,c21,c22,c23,c24,c25,c26,c27,c28,c29 0AB1: E008E708 0AB5: ED08 defw c30,c31,c32 0AB7: EF08F008 0ABB: F308F908 0ABF: FE080409 0AC3: 0A09 charset_ptr: defw c33,c34,c35,c36,c37,c38,c39 0AC5: 0B090D09 0AC9: 0F091409 0ACD: 19091B09 0AD1: 20092209 0AD5: 27092C09 defw c40,c41,c42,c43,c44,c45,c46,c47,c48,c49 0AD9: 31093609 0ADD: 3B094009 0AE1: 45094A09 0AE5: 4F095409 0AE9: 59095A09 defw c50,c51,c52,c53,c54,c55,c56,c57,c58,c59 0AED: 5C095F09 0AF1: 63096609 0AF5: 6B097109 0AF9: 76097B09 0AFD: 80098509 defw c60,c61,c62,c63,c64,c65,c66,c67,c68,c69 0B01: 8A098F09 0B05: 94099909 0B09: 9C09A009 0B0D: A509A909 0B11: AF09B509 defw c70,c71,c72,c73,c74,c75,c76,c77,c78,c79 0B15: BB09C009 0B19: C609CB09 0B1D: D009D509 0B21: DA09DF09 0B25: E509EB09 defw c80,c81,c82,c83,c84,c85,c86,c87,c88,c89 0B29: F009F609 0B2D: F909FE09 0B31: 010A060A 0B35: 0A0A0F0A 0B39: 140A190A defw c90,c91,c92,c93,c94,c95,c96,c97,c98,c99 0B3D: 1D0A220A 0B41: 270A2A0A 0B45: 2F0A340A 0B49: 370A3B0A 0B4D: 3F0A420A defw c100,c101,c102,c103,c104,c105,c106,c107,c108,c109 0B51: 490A4E0A 0B55: 530A580A 0B59: 5D0A610A 0B5D: 660A6A0A 0B61: 6F0A740A defw c110,c111,c112,c113,c114,c115,c116,c117,c118,c119 0B65: 790A7E0A 0B69: 820A870A 0B6D: 8B0A8C0A 0B71: 900A940A 0B75: 9C0A defw c120,c121,c122,c123,c124,c125,c126,c127,c128 0B77: 0B77: 0B77: 0B77: 0B77: #include "charset.ass" 0B77: print_end equ $ 0B77: 0B77: screen_start equ $ 0B77: 0B77: ; -------------------------------------------------------- 0B77: ; S C R E E N - U T I L I T I E S 0B77: ; -------------------------------------------------------- 0B77: 0B77: ; scr_set_border A -- A 0B77: 0B77: ; clear_32_bytes IY DE E -- DE++ 0B77: ; copy_32_bytes IY HL DE BC -- HL++ DE++ BC++ 0B77: ; calc_ix_for_clear_c C -- IX 0B77: ; calc_ix_for_copy_c C -- IX 0B77: 0B77: ; clear_bc HL BC -- HL++ 0B77: ; clear_bc_a HL BC A -- HL++ 0B77: ; clear_bc_e HL BC E -- HL++ 0B77: 0B77: ; clear_pixels HL B C -- 0B77: ; clear_attributes HL B C A -- 0B77: ; clear_attributes_with_e_quick HL B C E -- 0B77: ; clear_screen_with_attr A -- 0B77: ; clear_cbox_with_attr HL B C A -- 0B77: 0B77: ; copy_bc HL DE BC -- HL++ DE++ BC=0 0B77: ; copy_pixels_to_buffer HL DE B C -- 0B77: ; copy_buffer_to_pixels HL DE B C -- 0B77: ; copy_attributes_to_buffer HL DE B C -- 0B77: ; copy_buffer_to_attributes HL DE B C -- 0B77: 0B77: ; scroll_cbox_up HL B C -- 0B77: 0B77: ; calc_hl_for_next_pixel_row HL -- HL 0B77: ; calc_de_for_next_pixel_row DE -- DE 0B77: ; adjust_hl_for_next_row HL -- HL 0B77: ; adjust_de_for_next_row DE -- DE 0B77: ; calc_hl_down_8_pixel_rows HL -- HL 0B77: 0B77: ; calc_attr_hl_for_pixel_hl HL -- HL 0B77: ; calc_pixel_hl_from_attr_hl HL -- HL 0B77: ; calc_attr_hl_for_row_b_col_c B C -- HL 0B77: ; calc_pixel_hl_for_row_b_col_c B C -- HL 0B77: ; calc_row_b_col_c_for_pixel_hl HL -- BC 0B77: ; calc_row_b_col_c_for_attr_hl HL -- BC 0B77: 0B77: 0B77: ula_out_byte data 1 0B77: 0B77: 0B77: ; -------------------------------------------------- 0B77: ; Setze Border-Farbe 0B77: ; 0B77: ; in: a = new color 0B77: ; out: a = current border color [0..7] 0B77: ; mod: af 0B77: 0B77: scr_set_border: 0B77: E607 and 7 0B79: 32165B ld (ula_out_byte),a 0B7C: D3FE out ($FE),a 0B7E: C9 ret 0B7F: 0B7F: 0B7F: ; -------------------------------------------------- 0B7F: ; Setze Border-Farbe erneut auf den alten Wert 0B7F: ; 0B7F: ; in: -- 0B7F: ; out: a = current border color [0..7] 0B7F: ; mod: af 0B7F: 0B7F: scr_restore_border: 0B7F: 3A165B ld a,(ula_out_byte) 0B82: D3FE out ($FE),a 0B84: C9 ret 0B85: 0B85: 0B85: 0B85: ; -------------------------------------------------- 0B85: ; Lösche 32 Bytes im Bildschirm 0B85: ; (HL)++ = E 0B85: ; 0B85: ; Der zu löschende Bereich muss vollständig in einem 256-Byte-Block liegen, 0B85: ; was beim Bildschirm immer der Fall ist. H wird nicht incrementiert, 0B85: ; und wenn der zu löschende Bereich an einer 256-Byte-Grenze endet, muss der 0B85: ; Aufrufer H selbst incrementieren. Dazu kann er sofort das Z-Flag prüfen. 0B85: ; Beim Bildschirm-Löschen ist es aber sehr günstig, dass H nicht verändert wird, 0B85: ; da man beim Weiterschalten innerhalb einer Zeichenzeile dann immer L restauriert 0B85: ; und H incrementiert. 0B85: ; 0B85: ; Die verwendete Methode ist vermutlich die zweitschnellste nach 0B85: ; Löschen mit push dd. Hier muss aber nicht der Interrupt (immer wieder) 0B85: ; ausgeschaltet werden und es kann auch eine ungerade Anzahl von Bytes leichter 0B85: ; gelöscht werden. 0B85: ; Das Löschen von beliebigen Speicherbereichen ist allerding hiermit nicht ideal, 0B85: ; weil das Splitten an den 256-Byte-Grenzen unverhältnismäßig aufwendig ist. 0B85: ; 0B85: ; in: IY: Rücksprungadresse 0B85: ; HL -> Ziel 0B85: ; E = Füllbyte 0B85: ; out: L++ 0B85: ; F: Z: L overflowed -> H++ needed. 0B85: ; mod: F, L 0B85: 0B85: clear_32_bytes: 0B85: 73 ld (hl),e ; 7 T 0B86: 2C inc l ; 4 T 0B87: 0B87: clear_31_bytes: 0B87: 73 ld (hl),e 0B88: 2C inc l 0B89: 73 ld (hl),e 0B8A: 2C inc l 0B8B: 73 ld (hl),e 0B8C: 2C inc l 0B8D: 73 ld (hl),e 0B8E: 2C inc l 0B8F: 73 ld (hl),e 0B90: 2C inc l 0B91: 73 ld (hl),e 0B92: 2C inc l 0B93: 73 ld (hl),e 0B94: 2C inc l 0B95: 73 ld (hl),e 0B96: 2C inc l 0B97: 73 ld (hl),e 0B98: 2C inc l 0B99: 73 ld (hl),e 0B9A: 2C inc l 0B9B: 73 ld (hl),e 0B9C: 2C inc l 0B9D: 73 ld (hl),e 0B9E: 2C inc l 0B9F: 73 ld (hl),e 0BA0: 2C inc l 0BA1: 73 ld (hl),e 0BA2: 2C inc l 0BA3: 73 ld (hl),e 0BA4: 2C inc l 0BA5: 73 ld (hl),e 0BA6: 2C inc l 0BA7: 73 ld (hl),e 0BA8: 2C inc l 0BA9: 73 ld (hl),e 0BAA: 2C inc l 0BAB: 73 ld (hl),e 0BAC: 2C inc l 0BAD: 73 ld (hl),e 0BAE: 2C inc l 0BAF: 73 ld (hl),e 0BB0: 2C inc l 0BB1: 73 ld (hl),e 0BB2: 2C inc l 0BB3: 73 ld (hl),e 0BB4: 2C inc l 0BB5: 73 ld (hl),e 0BB6: 2C inc l 0BB7: 73 ld (hl),e 0BB8: 2C inc l 0BB9: 73 ld (hl),e 0BBA: 2C inc l 0BBB: 73 ld (hl),e 0BBC: 2C inc l 0BBD: 73 ld (hl),e 0BBE: 2C inc l 0BBF: 73 ld (hl),e 0BC0: 2C inc l 0BC1: 73 ld (hl),e 0BC2: 2C inc l 0BC3: 73 ld (hl),e 0BC4: 2C inc l ; <- der evtl. Übertrag muss vom Aufrufer behandelt werden. 0BC5: 0BC5: clear_0_bytes: 0BC5: FDE9 jp (iy) 0BC7: 0BC7: 0BC7: 0BC7: ; -------------------------------------------------- 0BC7: ; Kopiere 32 Bytes 0BC7: ; (hl++) -> (de++) und bc-- 0BC7: ; 0BC7: ; in: iy: Rücksprungadresse 0BC7: ; hl -> Quelle 0BC7: ; de -> Ziel 0BC7: ; bc = Zähler 0BC7: ; out: hl++ 0BC7: ; de++ 0BC7: ; bc-- 0BC7: ; mod: f, bc, de, hl 0BC7: 0BC7: copy_32_bytes: 0BC7: EDA0 ldi ; 16 T 0BC9: 0BC9: copy_31_bytes: 0BC9: EDA0 ldi ; ld (de++),(hl++) 0BCB: EDA0 ldi ; bc-- 0BCD: EDA0 ldi 0BCF: EDA0 ldi 0BD1: EDA0 ldi 0BD3: EDA0 ldi 0BD5: EDA0 ldi 0BD7: EDA0 ldi 0BD9: EDA0 ldi 0BDB: EDA0 ldi 0BDD: EDA0 ldi 0BDF: EDA0 ldi 0BE1: EDA0 ldi 0BE3: EDA0 ldi 0BE5: EDA0 ldi 0BE7: EDA0 ldi 0BE9: EDA0 ldi 0BEB: EDA0 ldi 0BED: EDA0 ldi 0BEF: EDA0 ldi 0BF1: EDA0 ldi 0BF3: EDA0 ldi 0BF5: EDA0 ldi 0BF7: EDA0 ldi 0BF9: EDA0 ldi 0BFB: EDA0 ldi 0BFD: EDA0 ldi 0BFF: EDA0 ldi 0C01: EDA0 ldi 0C03: EDA0 ldi 0C05: EDA0 ldi 0C07: 0C07: copy_0_bytes: 0C07: FDE9 jp (iy) 0C09: 0C09: 0C09: 0C09: ; ------------------------------------------------- 0C09: ; Berechne Einsprungsadresse in clear_32_bytes 0C09: ; 0C09: ; in: c = bytes [0..c..32] 0C09: ; out: ix -> Einsprungsadresse für jp (ix) 0C09: ; mod: af, ix 0C09: 0C09: calc_ix_for_clear_c: 0C09: DD21850B ld ix,clear_32_bytes 0C0D: 1804 jr calc_ix 0C0F: 0C0F: 0C0F: 0C0F: ; ------------------------------------------------- 0C0F: ; Berechne Einsprungsadresse in copy_32_bytes 0C0F: ; 0C0F: ; in: c = bytes [0..c..32] 0C0F: ; out: ix -> Einsprungsadresse für jp (ix) 0C0F: ; mod: af, ix 0C0F: 0C0F: calc_ix_for_copy_c: 0C0F: DD21C70B ld ix,copy_32_bytes 0C13: 0C13: calc_ix: 0C13: 3E40 ld a,64 0C15: 91 sub c 0C16: 91 sub c 0C17: DD85 add xl 0C19: DD6F ld xl,a 0C1B: D0 ret nc 0C1C: DD24 inc xh 0C1E: C9 ret 0C1F: 0C1F: 0C1F: 0C1F: ; ------------------------------------------------ 0C1F: ; Lösche BC Bytes mit $00. 0C1F: ; 0C1F: ; in: hl dest 0C1F: ; bc count 0C1F: ; out: hl++ 0C1F: ; mod: af, bc, de, hl 0C1F: 0C1F: clear_bc: 0C1F: 97 sub a 0C20: ;jr clear_bc_a 0C20: 0C20: 0C20: 0C20: ; ------------------------------------------------ 0C20: ; Lösche BC Bytes. 0C20: ; 0C20: ; in: hl dest 0C20: ; bc count 0C20: ; a filler 0C20: ; out: hl++ 0C20: ; mod: af, bc, de, hl 0C20: 0C20: clear_bc_a: 0C20: 5F ld e,a ; e = filler 0C21: 0C21: clear_bc_e: 0C21: 04 inc b ; b = outer loop counter 0C22: 1604 ld d,4 ; d = 4 0C24: 79 ld a,c ; a = inner loop counter; bits 0&1 = remainder 0C25: 1808 jr cbc4 0C27: 0C27: 73 cbc3 ld (hl),e 0C28: 23 inc hl 0C29: 73 ld (hl),e 0C2A: 23 inc hl 0C2B: 73 ld (hl),e 0C2C: 23 inc hl 0C2D: 73 ld (hl),e 0C2E: 23 inc hl 0C2F: 0C2F: 92 cbc4 sub d ; 4 0C30: 30F5 jr nc,cbc3 0C32: 0C32: 05 dec b 0C33: 10F2 djnz cbc3 0C35: 0C35: ; a = remainder 0C35: 0C35: 0F cbcx rrca 0C36: 3002 jr nc,cbc5 0C38: 73 ld (hl),e 0C39: 23 inc hl 0C3A: 0C3A: 0F cbc5 rrca 0C3B: D0 ret nc 0C3C: 73 ld (hl),e 0C3D: 23 inc hl 0C3E: 73 ld (hl),e 0C3F: 23 inc hl 0C40: C9 ret 0C41: 0C41: 0C41: 0C41: ; ------------------------------------------------------------ 0C41: ; Lösche die Pixel ab HL für B x C Character Cells 0C41: ; 0C41: ; in: hl -> 1. screen byte 0C41: ; b = rows 0C41: ; c = columns 0C41: ; out: -- 0C41: ; mod: AF, IY 0C41: 0C41: clear_pixels_no_exx: 0C41: clear_pixels: 0C41: D7 rst save_registers 0C42: 7C ld a,h 0C43: E6F8 and $F8 ; %010bbzzz -> %010bb000 0C45: 67 ld h,a ; force legal: hl -> top row of character cell 0C46: 0C46: clear_pixels_quick: 0C46: 1E00 ld e,0 ; E = fill byte = 0 0C48: DDE5 push ix 0C4A: CD090C call calc_ix_for_clear_c 0C4D: FD21570C ld iy,clrret ; return address from jp(ix) 0C51: 48 ld c,b ; C = rows = outer counter 0C52: 0C52: ; loop over B character rows: 0C52: 0608 cb80 ld b,8 ; b = counter = 8 pixel rows 0C54: 7D ld a,l ; L retten 0C55: 0C55: ; loop over 8 pixel rows: 0C55: DDE9 cb81 jp (ix) ; clear pixel row (hl)++ 0C57: 6F clrret ld l,a ; L erneuern 0C58: 24 inc h ; next pixel row 0C59: 10FA djnz cb81 ; next row inside character row 0C5B: 0C5B: CD040E call adjust_hl_for_next_row ; hl++ 0C5E: 0D dec c 0C5F: 20F1 jr nz,cb80 ; next character row 0C61: 0C61: DDE1 pop ix 0C63: C9 ret 0C64: 0C64: 0C64: 0C64: ; ------------------------------------------------------------ 0C64: ; Lösche die Attribute ab HL für B x C Character Cells 0C64: ; 0C64: ; in: a = attribute byte 0C64: ; hl -> 1. attribute byte 0C64: ; b = rows 0C64: ; c = columns 0C64: ; out: -- 0C64: ; mod: AF, IY 0C64: 0C64: clear_attributes_no_exx: 0C64: clear_attributes: 0C64: D7 rst save_registers 0C65: 0C65: clear_attributes_quick: 0C65: 5F ld e,a ; E = fill byte 0C66: 0C66: clear_attributes_with_e_quick: 0C66: DDE5 push ix 0C68: CD090C call calc_ix_for_clear_c 0C6B: FD21720C ld iy,claret ; return address from jp(ix) 0C6F: 7D ld a,l ; A = L for restore & increment 0C70: 0C70: ; loop over B rows: 0C70: DDE9 cb84 jp (ix) 0C72: C620 claret add 32 0C74: 6F ld l,a ; hl++ 0C75: 3001 jr nc,$+3 0C77: 24 inc h 0C78: 0C78: 10F6 djnz cb84 0C7A: 0C7A: DDE1 pop ix 0C7C: C9 ret 0C7D: 0C7D: 0C7D: 0C7D: ; ------------------------------------------------------------ 0C7D: ; Clear screen 0C7D: ; Löscht Pixel mit 0x00 und Attribute mit dem Wert aus A. 0C7D: ; Setzt Border Color entsprechend der Paper Color. 0C7D: ; Um den Eindruck eines instantanen Löschens ohne pixel/attr out-of-sync-Blitzer 0C7D: ; zu erzeugen, werden die Attribute zunächst zusätzlich mit pen=paper color gelöscht. 0C7D: ; 0C7D: ; in: A = new attribute 0C7D: ; out: -- 0C7D: ; mod: AF, IY 0C7D: 0C7D: clear_screen_with_attr_no_exx: 0C7D: clear_screen_with_attr: 0C7D: D7 rst save_registers 0C7E: 0C7E: F5 push af ; attr retten 0C7F: 0C7F: E6F8 and $F8 0C81: 5F ld e,a ; e = attribut ohne pen bits 0C82: 1F rra 0C83: 1F rra 0C84: 1F rra 0C85: ;and 7 ; a = paper bits moved to pen position 0C85: ;out ($fe),a ; set border 0C85: CD770B call scr_set_border 0C88: B3 or e ; a = attr mit pen == paper 0C89: 0C89: 210058 ld hl,$5800 ; start of attr 0C8C: 012018 ld bc,24*256+32 ; 24 rows, 32 cols 0C8F: CD650C call clear_attributes_quick ; quick => also no exx 0C92: 0C92: F1 pop af ; attr 0C93: 210040 ld hl,$4000 0C96: 012018 ld bc,24*256 + 32 0C99: 1801 jr clear_cbox_with_attr_quick ; quick -> also no exx 0C9B: 0C9B: 0C9B: 0C9B: ; ------------------------------------------------------------ 0C9B: ; clear B rows á C character cells 0C9B: ; 0C9B: ; Löscht 8x pixel mit $00 + 1x attr je Feld mit print_attr 0C9B: ; 0C9B: ; in: a = attribute 0C9B: ; b = rows 0C9B: ; c = columns 0C9B: ; hl -> 1. screen byte 0C9B: ; out: -- 0C9B: ; mod: AF, IY 0C9B: 0C9B: clear_cbox_with_attr_no_exx: 0C9B: clear_cbox_with_attr: 0C9B: D7 rst save_registers 0C9C: 0C9C: clear_cbox_with_attr_quick: 0C9C: 5F ld e,a ; attr 0C9D: CD410C call clear_pixels 0CA0: CD270E call calc_attr_hl_for_pixel_hl 0CA3: C3660C jp clear_attributes_with_e_quick ; quick => also no exx 0CA6: 0CA6: 0CA6: 0CA6: ; ------------------------------------------------ 0CA6: ; slightly faster ldir. 0CA6: ; Rejecting BC=0 0CA6: ; Lohnt sich erst ab ca. 26 Bytes. 0CA6: ; kopiert bc Bytes von hl++ nach de++. 0CA6: ; 0CA6: ; Overhead für 0 Bytes: 15+18+71+21 = 131 0CA6: ; 15 Bytes: 15+18+71+21 -15*5 = 56 0CA6: ; 30 Bytes: 15+18+71+21 -30*5 = -19 0CA6: ; 0CA6: ; in: hl, de, bc 0CA6: ; out: hl++, de++, bc=0 0CA6: ; mod: af, bc, de, hl, iy 0CA6: 0CA6: copy_bc: 0CA6: 97 sub a ; 4 0CA7: B8 cp b ; 4 0CA8: 3814 jr c,cpbc1 ; 12 / 7 0CAA: ;jr copy_c 0CAA: 0CAA: 0CAA: 0CAA: ; ------------------------------------------------ 0CAA: ; kopiert C Bytes von hl++ nach de++. 0CAA: ; Rejecting C = 0 0CAA: ; B wird erhalten. 0CAA: ; Lohnt sich erst ab ca. 23 Bytes. 0CAA: ; 0CAA: ; in: hl, de, c 0CAA: ; out: hl++, de++, c=0 0CAA: ; mod: af, c, de, hl, iy 0CAA: 0CAA: 3E20 copy_c ld a,32 ; 7 0CAC: B9 cp c ; 4 0CAD: 3819 jr c,cpbc3 ; 12 / 7 0CAF: 0CAF: FDE1 cpbc5 pop iy ; 14 eigene Return-Adresse 0CB1: E5 push hl ; 11 retten 0CB2: 91 sub c ; 4 32-C 0CB3: 87 add a ; 4 2* (32-C) 0CB4: 0CB4: 21C70B ld hl,copy_32_bytes ; 11 0CB7: 85 add l ; 4 0CB8: 6F ld l,a ; 4 0CB9: 0CB9: #if copy_32_bytes/256 != copy_0_bytes/256 0CB9: 3001 jr nc,$+3 ; 12 / 7 0CBB: 24 inc h ; 0 / 4 0CBC: #endif 0CBC: E3 ex hl,(sp) ; 19 0CBD: C9 ret ; 27 (incl. call) 0CBE: 0CBE: FD21C20C cpbc1 ld iy,cpbc2 ; 14 0CC2: B8 cpbc2 cp b ; 4 0CC3: DAC70B jp c,copy_32_bytes ; 10 / 18 - 32*5 0CC6: 3E20 ld a,32 ; 7 0CC8: FD21CC0C cpbc3 ld iy,cpbc4 ; 14 0CCC: B9 cpbc4 cp c ; 4 0CCD: DAC70B jp c,copy_32_bytes ; 10 / 18 - 32*5 0CD0: 18DD jr cpbc5 ; 12 0CD2: 0CD2: 0CD2: 0CD2: ; ------------------------------------------ 0CD2: ; save screen pixels to buffer 0CD2: ; 0CD2: ; in: hl -> 1st pixel byte 0CD2: ; b = rows (characters) 0CD2: ; c = cols 0CD2: ; out: hl = handle 0CD2: ; mod: af,iy 0CD2: 0CD2: scr_save_pixels_no_exx: 0CD2: scr_save_pixels: 0CD2: C5 push bc 0CD3: D5 push de 0CD4: 0CD4: ; allocate buffer 0CD4: E5 push hl ; sp: -> source 0CD5: C5 push bc ; sp: b=rows and c=cols 0CD6: CDF220 call mult_bc ; hl = b x c 0CD9: 29 add hl,hl ; characters are 8 pixel rows each 0CDA: 23 inc hl ; +4 for source address, rows and cols 0CDB: 29 add hl,hl ; hl = size := hl*8 0CDC: 29 add hl,hl 0CDD: 4D44 ld bc,hl ; bc = size 0CDF: CD0010 call mem_heap_alloc ; hl -> handle, de -> dest; bc=size 0CE2: C1 pop bc ; b=rows, c=cols 0CE3: E3 ex hl,(sp) ; sp: handle; hl->source; de->dest; bc=rows/cols 0CE4: 0CE4: ; store 1st pixel address, rows and cols in buffer: 0CE4: CD310D call up_store_hlbc_to_de 0CE7: 0CE7: ; setup copy routine 0CE7: DDE5 push ix 0CE9: CD0F0C call calc_ix_for_copy_c ; setup IX from C 0CEC: FD21F70C ld iy,pcp1ret ; ix = return address from ldi-routine 0CF0: 0CF0: ; copy B character rows: 0CF0: C5 pcp0 push bc ; B = row count down, C = cols 0CF1: 010009 ld bc,9*256 ; B: 8 rows; +1 because c will underflow 1x 0CF4: ; C: 0 => will 1x overflow and decr b 0CF4: 7D ld a,l ; save l to restore hl 0CF5: 0CF5: ; copy 8 pixel rows: 0CF5: DDE9 pcp1 jp (ix) ; copy C bytes 0CF7: 6F pcp1ret ld l,a ; restore hl 0CF8: 24 inc h ; hl+=256 => skip over remainder of row 0CF9: 10FA djnz pcp1 0CFB: 0CFB: CD040E call adjust_hl_for_next_row ; adjust hl for next character row 0CFE: C1 pop bc 0CFF: 10EF djnz pcp0 ; B runterzählen 0D01: 0D01: 1828 jr pop_ixhldebc 0D03: 0D03: 0D03: 0D03: ; ------------------------------------------ 0D03: ; copy attributes to buffer 0D03: ; 0D03: ; in: hl -> 1st attr byte 0D03: ; b = rows (characters) 0D03: ; c = cols 0D03: ; out: handle 0D03: ; mod: af 0D03: 0D03: scr_save_attributes_no_exx: 0D03: scr_save_attributes: 0D03: C5 push bc 0D04: D5 push de 0D05: 0D05: ; allocate buffer: 0D05: E5 push hl ; sp: -> source 0D06: C5 push bc ; sp: b=rows and c=cols 0D07: CDF220 call mult_bc ; hl = b x c 0D0A: 23 inc hl ; add 2 bytes to store rows and cols 0D0B: 23 inc hl 0D0C: 23 inc hl ; add 2 bytes to store 1st attr byte address 0D0D: 23 inc hl 0D0E: 4D44 ld bc,hl ; bc = size 0D10: CD0010 call mem_heap_alloc ; hl -> handle, de -> dest; bc=size 0D13: C1 pop bc ; b=rows, c=cols 0D14: E3 ex hl,(sp) ; sp: handle; hl->source; de->dest; bc=rows/cols 0D15: 0D15: ; store source, rows and cols in buffer 0D15: CD310D call up_store_hlbc_to_de ; store hlbc via de++ 0D18: 0D18: ; setup copy routine 0D18: DDE5 push ix 0D1A: CD0F0C call calc_ix_for_copy_c ; setup IX from C 0D1D: FD21270D ld iy,pca1ret ; iy = return address from ldi-routine 0D21: 78 ld a,b ; a = rows 0D22: 0D22: ; copy A attr rows: 0D22: 012000 pca0 ld bc,32 ; bc = offset of attribute rows 0D25: DDE9 jp (ix) ; copy C bytes 0D27: 09 pca1ret add hl,bc ; skip over remainder of row 0D28: 3D dec a 0D29: 20F7 jr nz,pca0 0D2B: 0D2B: pop_ixhldebc: 0D2B: DDE1 pop ix ; ix 0D2D: E1 pop hl ; handle 0D2E: D1 pop de ; de 0D2F: C1 pop bc ; bc 0D30: C9 ret 0D31: 0D31: up_store_hlbc_to_de: 0D31: EB ex hl,de 0D32: 73 ld (hl),e ; store source address 0D33: 23 inc hl 0D34: 72 ld (hl),d 0D35: 23 inc hl 0D36: 70 ld (hl),b ; store rows 0D37: 23 inc hl 0D38: 71 ld (hl),c ; store cols 0D39: 23 inc hl 0D3A: EB ex hl,de 0D3B: C9 ret 0D3C: 0D3C: 0D3C: 0D3C: ; ------------------------------------------ 0D3C: ; copy buffer back to screen pixels 0D3C: ; handle from heap 0D3C: ; 0D3C: ; in: -- 0D3C: ; out: -- 0D3C: ; mod: af 0D3C: 0D3C: v_restore_pixels: ; opcode v_restore_pixels -- 0D3C: CD410D call scr_restore_pixels 0D3F: FDE9 jp (iy) 0D41: 0D41: scr_restore_pixels_no_exx: 0D41: scr_restore_pixels: 0D41: C5 push bc 0D42: D5 push de 0D43: E5 push hl 0D44: DDE5 push ix 0D46: FDE5 push iy 0D48: CD950F call mem_heap_pop_handle ; hl -> handle 0D4B: CD5C0F call mem_get_address ; hl -> source data 0D4E: 0D4E: ; restore 1st pixel address, rows and cols in buffer: 0D4E: 5E ld e,(hl) ; 1st pixel address 0D4F: 23 inc hl 0D50: 56 ld d,(hl) 0D51: 23 inc hl 0D52: 46 ld b,(hl) ; rows 0D53: 23 inc hl 0D54: 4E ld c,(hl) ; cols 0D55: 23 inc hl ; bc=rows/cols; hl->buffer; de->1st pixel 0D56: 0D56: ; setup copy routine: 0D56: CD0F0C call calc_ix_for_copy_c ; setup IX from C 0D59: FD21640D ld iy,pp1ret ; iy = return address from ldi-routine 0D5D: 0D5D: ; copy B character rows: 0D5D: C5 pp0 push bc ; B = row count down, C = cols 0D5E: 010009 ld bc,9*256 ; B: 8 rows; (+1 because c will underflow 1x) 0D61: ; C: will underflow 1x and decr b 0D61: 7B ld a,e ; a: save e for restore de 0D62: 0D62: ; copy 8 pixel rows: 0D62: DDE9 pp1 jp (ix) ; copy one row 0D64: 5F pp1ret ld e,a ; restore de 0D65: 14 inc d ; next pixel row: de += 256 0D66: 10FA djnz pp1 0D68: 0D68: CD130E call adjust_de_for_next_row ; adjust hl for next character row 0D6B: C1 pop bc 0D6C: 10EF djnz pp0 ; next row 0D6E: 0D6E: pop_iyixhldebc_dealloc: 0D6E: FDE1 pop iy 0D70: pop_ixhldebc_dealloc: 0D70: DDE1 pop ix 0D72: E1 pop hl 0D73: D1 pop de 0D74: C1 pop bc 0D75: C9 ret 0D76: 0D76: 0D76: 0D76: 0D76: ; ------------------------------------------ 0D76: ; copy buffer back to screen attributes 0D76: ; hl from heap 0D76: ; 0D76: ; in: -- 0D76: ; out: -- 0D76: ; mod: af 0D76: 0D76: v_restore_attributes: ; opcode v_restore_attributes -- 0D76: CD7B0D call scr_restore_attributes 0D79: FDE9 jp (iy) 0D7B: 0D7B: scr_restore_attributes_no_exx: 0D7B: scr_restore_attributes: 0D7B: C5 push bc 0D7C: D5 push de 0D7D: E5 push hl 0D7E: DDE5 push ix 0D80: FDE5 push iy 0D82: CD950F call mem_heap_pop_handle ; hl -> handle 0D85: CD5C0F call mem_get_address ; hl -> source data 0D88: 0D88: ; restore 1st attr address, rows and cols in buffer: 0D88: 5E ld e,(hl) ; 1st attr address 0D89: 23 inc hl 0D8A: 56 ld d,(hl) 0D8B: 23 inc hl 0D8C: 46 ld b,(hl) ; rows 0D8D: 23 inc hl 0D8E: 4E ld c,(hl) ; cols 0D8F: 23 inc hl ; bc=rows/cols; hl->buffer; de->1st attr 0D90: 0D90: ; copy: 0D90: CD0F0C call calc_ix_for_copy_c ; setup IX from C 0D93: FD219D0D ld iy,ppa2ret ; iy = return address from ldi-routine 0D97: 78 ld a,b ; a = rows 0D98: 0D98: 012000 ppa3 ld bc,32 ; offset of attr rows 0D9B: DDE9 jp (ix) ; copy C bytes 0D9D: EB ppa2ret ex hl,de 0D9E: 09 add hl,bc ; skip over remainder of row 0D9F: EB ex hl,de 0DA0: 3D dec a 0DA1: 20F5 jr nz,ppa3 ; B runterzählen, C bewahren! 0DA3: 0DA3: 18C9 jr pop_iyixhldebc_dealloc 0DA5: 0DA5: 0DA5: 0DA5: ; ------------------------------------------------------------ 0DA5: ; Scroll screen up: B rows, C cols 0DA5: ; 0DA5: ; scrolls C columns up by 1 character row 0DA5: ; scrolls B-1 rows and clears bottom row with print_attr 0DA5: ; scrolls pixels and attributes 0DA5: ; printing position etc. are not updated 0DA5: ; 0DA5: ; in: hl -> current screen byte 0DA5: ; b = rows 0DA5: ; c = cols 0DA5: ; out: -- 0DA5: ; mod: AF, IY, exx 0DA5: 0DA5: scroll_cbox_up_save_exx: 0DA5: DF rst save_exx_registers 0DA6: 0DA6: scroll_cbox_up: 0DA6: D7 rst save_registers 0DA7: 0DA7: 78 ld a,b ; Security: 0DA8: B1 or c ; trap 0-wide or 0-high blocks 0DA9: C8 ret z 0DAA: F8 ret m 0DAB: 0DAB: 7C ld a,h ; Force legal: 0DAC: E6F8 and $F8 ; hl -> top pixel row of character row 0DAE: 67 ld h,a 0DAF: 0DAF: scroll_cbox_up_quick: 0DAF: DDE5 push ix 0DB1: CD0F0C call calc_ix_for_copy_c ; setup IX 0DB4: 0DB4: ; prepare copy pixels: 0DB4: E5 push hl ; hl für copy attr 0DB5: 5D54 ld de,hl ; de -> upper row = dest 0DB7: CD1D0E call calc_hl_down_8_pixel_rows ; hl -> lower row = source 0DBA: 0DBA: ; prepare copy attributes: 0DBA: D9 exx ; attr set 0DBB: E1 pop hl 0DBC: CD270E call calc_attr_hl_for_pixel_hl 0DBF: EB ex hl,de ; de -> upper row = dest 0DC0: 212000 ld hl,32 0DC3: 19 add hl,de ; hl -> lower row = source 0DC4: D9 exx ; pixel set 0DC5: 0DC5: 1829 jr psb3 ; copy b-1 rows; maybe 0 0DC7: 0DC7: ; --- main loop: copy B-1 character rows: --- 0DC7: 0DC7: ; copy 8 pixel rows: 0DC7: 3E08 psb0 ld a,8 ; 8 rows 0DC9: FD21D30D ld iy,psb1ret 0DCD: 0DCD: C5 push bc ; B = row count down, C = cols 0DCE: 0DCE: 010001 psb1 ld bc,256 ; offset of pixel rows inside character rows 0DD1: DDE9 jp (ix) ; copy C bytes 0DD3: 09 psb1ret add hl,bc ; skip over remainder of row 0DD4: EB ex hl,de 0DD5: 09 add hl,bc 0DD6: EB ex hl,de 0DD7: 3D dec a 0DD8: 20F4 jr nz,psb1 0DDA: 0DDA: C1 pop bc 0DDB: 0DDB: CD040E call adjust_hl_for_next_row ; adjust de and hl for next character row 0DDE: CD130E call adjust_de_for_next_row 0DE1: 0DE1: ; copy 1 attribute row: 0DE1: D9 exx ; attr set 0DE2: FD21EB0D ld iy,psa1ret 0DE6: 012000 psa1 ld bc,32 ; offset of attr rows 0DE9: DDE9 jp (ix) ; copy C bytes 0DEB: 09 psa1ret add hl,bc ; skip over remainder of row 0DEC: EB ex hl,de 0DED: 09 add hl,bc 0DEE: EB ex hl,de 0DEF: D9 exx ; pixel set 0DF0: 0DF0: 10D5 psb3 djnz psb0 ; B runterzählen, C bewahren! 0DF2: 0DF2: ; --- end of main loop --- 0DF2: 0DF2: DDE1 pop ix ; ix 0DF4: 0DF4: EB ex hl,de ; hl -> pixels of the last character row 0DF5: ;ld c,c ; c = columns 0DF5: 04 inc b ; b = 1 row 0DF6: 0DF6: C5 push bc 0DF7: CD460C call clear_pixels_quick 0DFA: C1 pop bc 0DFB: D9 exx ; hl -> attr of the last character row 0DFC: C3650C jp clear_attributes_quick 0DFF: 0DFF: 0DFF: 0DFF: 0DFF: 0DFF: ; ---------------------------------------- 0DFF: ; advance hl vertically to next pixel row 0DFF: ; 0DFF: ; screen layout: 0DFF: ; 0DFF: ; %010ccaaa.bbbzzzzz 0DFF: ; 0DFF: ; zzzzz = character column 0DFF: ; aaa = row inside character row 0DFF: ; bbb = character row inside screen block 0DFF: ; cc = screen block 0DFF: ; 0DFF: ; in: HL 0DFF: ; out: HL 0DFF: ; mod: AF, HL 0DFF: 0DFF: calc_hl_for_next_pixel_row: 0DFF: 24 inc h ; aaa += 1 0E00: 7C ld a,h 0E01: E607 and 7 0E03: C0 ret nz ; advance pixel row inside a character row 0E04: 0E04: ; aaa++ overflowed to cc 0E04: ; => add the overflow to bbb 0E04: 0E04: ; this is also a good entry after incrementing H 8 times for a character row 0E04: ; to adjust HL to the next pixel row, the first row of the next character row. 0E04: 0E04: adjust_hl_for_next_row: 0E04: 7D ld a,l 0E05: C620 add 32 0E07: 6F ld l,a ; bbb++ 0E08: 0E08: ; now undo the overflow to cc 0E08: ; except if there was also an overflow from bbb++ 0E08: ; in which case the overflow to cc is fine (though it came from bbb++, not aaa++) 0E08: 0E08: D8 ret c ; bbb++ did overflow => ok => exit 0E09: 0E09: ; undo the overflow to cc: 0E09: 0E09: 7C ld a,h 0E0A: D608 sub 8 0E0C: 67 ld h,a ; cc-- 0E0D: C9 ret 0E0E: 0E0E: 0E0E: 0E0E: ; ---------------------------------------- 0E0E: ; Advance de vertically to next pixel row. 0E0E: ; das selbe nur für DE: 0E0E: 0E0E: calc_de_for_next_pixel_row: 0E0E: 14 inc d 0E0F: 7A ld a,d 0E10: E607 and 7 0E12: C0 ret nz 0E13: adjust_de_for_next_row: 0E13: 7B ld a,e 0E14: C620 add 32 0E16: 5F ld e,a 0E17: D8 ret c 0E18: 7A ld a,d 0E19: D608 sub 8 0E1B: 57 ld d,a 0E1C: C9 ret 0E1D: 0E1D: 0E1D: 0E1D: ; ---------------------------------------- 0E1D: ; advance hl vertically to next character row 0E1D: ; 0E1D: ; column and pixel row inside character row 0E1D: ; are preserved. 0E1D: ; 0E1D: ; in: HL 0E1D: ; out: HL 0E1D: ; mod: AF, HL 0E1D: 0E1D: calc_hl_down_8_pixel_rows: 0E1D: 7D ld a,l 0E1E: C620 add 32 0E20: 6F ld l,a ; bbb++ 0E21: D0 ret nc 0E22: 0E22: ; overflow to cc: 0E22: 7C ld a,h 0E23: C608 add 8 0E25: 67 ld h,a ; cc++ 0E26: C9 ret 0E27: 0E27: 0E27: 0E27: ; ------------------------------------------------------------ 0E27: ; UP: Berechne Attribut-Addresse HL zu Pixel (Byte) Adresse HL 0E27: ; 0E27: ; in: HL = Pixel-Adresse [$4000..$57FF] = %010bbzzz.rrrccccc 0E27: ; out: HL = Attribut-Adresse [$5800..$5AFF] = %010110bb.rrrccccc 0E27: ; mod: HL, AF 0E27: 0E27: calc_attr_hl_for_pixel_hl: 0E27: 7C ld a,h 0E28: 0F rrca 0E29: 0F rrca 0E2A: 0F rrca 0E2B: E603 and $03 0E2D: F658 or $58 0E2F: 67 ld h,a 0E30: C9 ret 0E31: 0E31: 0E31: 0E31: ; ------------------------------------------------------------ 0E31: ; UP: Berechne Pixel-Addresse HL zu Attribut-Adresse HL 0E31: ; Berechnet die Adresse des obersten Pixelbytes: hl & $0007 = 0 0E31: ; 0E31: ; in: HL = Attribut-Adresse [$5800..$5AFF] = %010110bb.rrrccccc 0E31: ; out: HL = Pixel-Byte-Adresse [$4000..$57FF] = %010bb000.rrrccccc 0E31: ; mod: HL, AF 0E31: 0E31: calc_pixel_hl_for_attr_hl: 0E31: 7C ld a,h 0E32: E60F and $0f 0E34: 07 rlca 0E35: 07 rlca 0E36: 07 rlca 0E37: 67 ld h,a 0E38: C9 ret 0E39: 0E39: 0E39: 0E39: ; ------------------------------------------------------------ 0E39: ; Berechne Attribut-Adresse für Zeile B Spalte C: 0E39: ; 0E39: ; in: B = character row [0..23] = %000bbrrr 0E39: ; C = character column [0..31] = %000ccccc 0E39: ; out: HL -> attribute byte = %010110bb.rrrccccc 0E39: ; mod: AF, HL 0E39: 0E39: calc_attr_hl_for_row_b_col_c: 0E39: 78 ld a,b ; a = %000bbrrr 0E3A: 2616 ld h,$58>>2 ; h = %00010110; $5800: Start of Attributes 0E3C: 07 rlca ; a = %00101100; cy=0 0E3D: 17 rla ; a = %01011000; cy=0 0E3E: 17 rla ; a = %bbrrr000; cy=0 0E3F: 17 rla ; a = %brrr0000; cy = b 0E40: CB14 rl h ; h = %0010110b; cy = 0 0E42: 17 rla ; a = %rrr00000; cy = b 0E43: CB14 rl h ; h = %010110bb = fertig 0E45: B1 or c ; a = %rrrccccc 0E46: 6F ld l,a ; l = %rrrccccc = fertig 0E47: C9 ret 0E48: 0E48: 0E48: 0E48: ; ------------------------------------------------------------ 0E48: ; Berechne Pixel-Adresse für Zeile B Spalte C: 0E48: ; Berechnet die Adresse des obersten Pixelbytes: hl & $0007 = 0 0E48: ; 0E48: ; in: B = character row [0..23] = %000bbrrr 0E48: ; C = character column [0..31] = %000ccccc 0E48: ; out: HL -> pixel byte = %010bb000.rrrccccc 0E48: ; mod: AF, HL 0E48: 0E48: calc_pixel_hl_for_row_b_col_c: 0E48: 78 ld a,b 0E49: 0F rrca 0E4A: 0F rrca 0E4B: 0F rrca 0E4C: E6E0 and $E0 ; a = %rrr00000 0E4E: B1 or c ; a = %rrrccccc 0E4F: 6F ld l,a ; l = %rrrccccc = fertig 0E50: 78 ld a,b ; a = %000bbrrr 0E51: E618 and $18 ; a = %000bb000 0E53: F640 or $40 ; a = %010bb000 0E55: 67 ld h,a ; h = %010bb000 = fertig 0E56: C9 ret 0E57: 0E57: 0E57: 0E57: ; ------------------------------------------------------------ 0E57: ; Berechne Zeile B und Spalte C zu einer Pixeladresse HL 0E57: ; 0E57: ; in: HL -> pixel byte = %010bbzzz.rrrccccc 0E57: ; out: B = character row [0..23] = %000bbrrr 0E57: ; C = character column [0..31] = %000ccccc 0E57: ; mod: AF, BC 0E57: 0E57: calc_row_b_col_c_for_pixel_hl: 0E57: 7C ld a,h ; a = %010bbzzz 0E58: E618 and $18 ; a = %000bb000 0E5A: 47 ld b,a ; b = %000bb000 0E5B: 0E5B: 7D ld a,l ; a = %rrrccccc 0E5C: E61F and $1f ; a = %000ccccc 0E5E: 4F ld c,a ; c = %000ccccc = feritg 0E5F: 0E5F: AD xor l ; a = %rrr00000 0E60: 07 rlca 0E61: 07 rlca 0E62: 07 rlca ; a = %00000rrr 0E63: B0 or b ; a = %000bbrrr 0E64: 47 ld b,a ; b = %000bbrrr = fertig 0E65: C9 ret 0E66: 0E66: 0E66: 0E66: ; ------------------------------------------------------------ 0E66: ; Berechne Zeile B und Spalte C zu einer Attributadresse HL 0E66: ; 0E66: ; in: HL -> attribute byte = %010110bb.rrrccccc 0E66: ; out: B = character row [0..23] = %000bbrrr 0E66: ; C = character column [0..31] = %000ccccc 0E66: ; mod: AF, BC 0E66: 0E66: calc_row_b_col_c_for_attr_hl: 0E66: 7C ld a,h ; a = %010110bb 0E67: E603 and 3 ; a = %000000bb 0E69: 47 ld b,a ; b = %000000bb 0E6A: 0E6A: 7D ld a,l ; a = %rrrccccc 0E6B: E61F and $1f ; a = %000ccccc 0E6D: 4F ld c,a ; c = %000ccccc = fertig 0E6E: 0E6E: AD xor l ; a = %rrr00000 0E6F: B0 or b ; a = %rrr000bb 0E70: 07 rlca 0E71: 07 rlca 0E72: 07 rlca ; a = %000bbrrr 0E73: 47 ld b,a ; b = %000bbrrr = fertig 0E74: C9 ret 0E75: 0E75: 0E75: 0E75: 0E75: 0E75: 0E75: 0E75: 0E75: #include "screen.ass" 0E75: screen_end equ $ 0E75: 0E75: mempack_start equ $ 0E75: 0E75: 0E75: ; -------------------------------------------------------- 0E75: ; Dynamische Speicherverwaltung 0E75: ; -------------------------------------------------------- 0E75: 0E75: ; Externe Aufrufe: 0E75: ; abort_oomem 0E75: ; scr_restore_border wg. Border-Gimmik in mem_compact 0E75: 0E75: 0E75: ; Mit diesem Modul kann der freie Speicher dynamisch verwaltet werden. 0E75: ; 0E75: ; Zugeteilter Speicher wird immer über ein ortsfestes Handle referenziert. 0E75: ; Pro Block werden zusätzlich 4 Bytes für Verwaltungsinformationen belegt: 0E75: ; das Handle und die Längenangabe. Handles werden aus einem Pool vergeben, 0E75: ; der von oben in den freien Speicher hinein wächst, während die Datenblöcke 0E75: ; selbst von unten her in den freien Speicher wachsen. 0E75: ; 0E75: ; Neben dem Handle-Pool für globale Variablen gibt es einen Heap und einen Stack. 0E75: ; Es können mehrere Handles auf den gleichen Datenblock zeigen. Es liegt dann 0E75: ; an der Applikation, mehrfach referenzierte Blocks zu kennen und zu beachten. 0E75: ; 0E75: ; 0-Byte-Blöcke belegen im freien Speicher nur die 2 Byte für das Handle. 0E75: ; Die Daten dazu, also die 2 Byte Längenangabe, stehen im ROM: mem_empty_data. 0E75: ; Dies wird in folgenden Routinen beachtet / ausgenutzt: 0E75: ; mem_alloc returns handle -> mem_empty_data 0E75: ; mem_compact ersetzt im 1. Lauf nicht die Adresse im Handle 0E75: ; 0E75: ; Belegte Blöcke im Datenbereich dürfen nicht 0 Byte lang sein, 0E75: ; freigegebene schon. Das kann passieren, wenn ein Datenblock um 2 Byte geshrinkt wurde. 0E75: ; mem_compact macht das keine Probleme, weil der 0 Byte block nicht mit ldir kopiert, 0E75: ; sondern übersprungen wird. 0E75: ; 0E75: ; Die maximale Größe für einen einzelnen Block ist $6000-1 = 24575 Bytes. 0E75: ; Dieses Limit wird für mem_compact benötigt, die eine Grenze zur 0E75: ; Unterscheidung von Handle-Adressen und Blockgrößen benötigt. 0E75: ; 0E75: ; Wenn eine Speicheranforderung nicht sofort befriedigt werden kann, 0E75: ; wird automatisch eine Garbage Collection durchgeführt. Diese hat einen 0E75: ; linearen Zusammenhang zwischen Anzahl angelegter Speicherblöcke plus 0E75: ; Gesamtgröße aller belegten Blöcke und Zeitverbrauch. 0E75: ; 0E75: ; Alle Routinen benutzen nur die Register AF bis HL. 0E75: ; Alle Register, bis auf AF, werden von allen Routinen nicht verändert, 0E75: ; wenn darin keine Werte zurückgegeben werden. 0E75: 0E75: 0E75: ; Speicheraufteilung: 0E75: 0E75: ; ========================================================================= 0E75: ; 0E75: mem_start data 2 0E75: mem_data_start equ mem_start 0E75: ; 0E75: ; Hier liegen die Datenblöcke. 0E75: ; jeder Datenblock beginnt mit 2 Byte Längenangabe. 0E75: ; Auch wieder frei gegebene Blöcke sind noch so verwaltet. 0E75: ; 0E75: mem_data_end data 2 0E75: mem_free_start equ mem_data_end 0E75: ; 0E75: ; Freier Speicher. 0E75: ; 0E75: mem_free_end data 2 0E75: mem_handles_start equ mem_free_end 0E75: ; 0E75: ; Handles. Freie Handles sind an handle.hi = 0 erkennbar. 0E75: ; Sonst zeigen sie auf die zugehörigen Daten. 0E75: ; 0E75: mem_last_handle data 2 0E75: ; zeigt auf das zuletzt vergebene Handle. 0E75: ; Bei der nächsten Anforderung wird ab dieser Stelle abwärts 0E75: ; nach einem neuen freien Handle gesucht. 0E75: ; 0E75: mem_handles_end data 2 0E75: mem_heap_start equ mem_handles_end 0E75: ; 0E75: ; Der Handle-Heap für mittlefristige, hierarchisch geschachtelte 0E75: ; Speicheranforderungen über Funktionsaufrufe hinweg. 0E75: ; 0E75: mem_heap_ptr data 2 0E75: ; 0E75: ; Freiraum zwischen Heap und Stack. 0E75: ; 0E75: mem_stack_ptr data 2 0E75: ; 0E75: ; Der Handle-Stack. Dieser ist für die kurzfristige Speicherung von Daten, 0E75: ; z.B. für lokale Variablen (Strings) oder Funktionsargumente und -Rückgabewerte. 0E75: ; 0E75: mem_stack_end data 2 0E75: mem_end equ mem_stack_end 0E75: ; 0E75: ; ========================================================================= 0E75: 0E75: 0E75: 0000 mem_empty_data defw 0 ; common data for all 0-byte requests 0E77: 0E77: lo equ 0 ; offset of low byte in word 0E77: hi equ 1 ; offset of high byte in word 0E77: 0E77: mem_max_size equ $6000 ; darunter auch bei 16K-Modell sicher keine Handles 0E77: mem_max_hi equ $60 0E77: 0E77: 0E77: ; ========================================================================= 0E77: ; Funktionen note: [handle] on heap; {handle} on stack. 0E77: 0E77: ; mem_init hl:mem_start de:mem_end+1 -- 0E77: ; mem_compact -- 0E77: 0E77: ; mem_get_free -- hl:size z|nz c|nc 0E77: ; mem_get_free_total -- hl:size z|nz c|nc 0E77: 0E77: ; mem_get_size_and_address hl:handleptr -- hl:dataptr bc:size 0E77: ; mem_get_address hl:handleptr -- hl:dataptr 0E77: ; mem_get_size hl:handleptr -- bc:size 0E77: ; mem_get_address_for_index hl:handleptr de:index -- hl:dataptr 0E77: ; mem_get_index_for_address hl:handleptr de:dataptr -- de:index 0E77: 0E77: ; mem_alloc bc:size -- hl:handleptr de:dataptr bc:size z|nz 0E77: ; mem_dealloc hl:handleptr -- 0E77: ; mem_new_handle -- hl:handleptr 0E77: ; mem_save_data hl:dataptr bc:size -- hl:handleptr 0E77: ; mem_restore_data hl:handleptr de:destptr -- 0E77: 0E77: ; mem_heap_alloc bc:size -- [handle] hl:handleptr de:dataptr bc:size z|nz 0E77: ; mem_heap_push_handle hl:handleptr -- [handle] 0E77: ; mem_heap_pop_handle [handle] -- hl:handleptr **unprotected!** 0E77: ; mem_heap_new_handle -- [handle] hl:handleptr 0E77: ; mem_heap_get_handle [handle] -- [handle] hl:handleptr 0E77: ; mem_heap_push_data hl:dataptr bc:size -- hl:handleptr 0E77: ; mem_heap_pop_data de:destptr -- 0E77: 0E77: ; mem_stack_alloc bc:size -- {handle} hl:handleptr de:dataptr bc:size z|nz 0E77: ; mem_stack_push_handle hl:handleptr -- {handle} 0E77: ; mem_stack_pop_handle {handle} -- hl:handleptr **unprotected!** 0E77: ; mem_stack_new_handle -- {handle} hl:handleptr 0E77: ; mem_stack_get_handle {handle} -- {handle} hl:handleptr 0E77: ; mem_stack_pick_handle de:index {handle_n..handle1} -- hl:handle_i_ptr 0E77: ; mem_stack_push_data hl:dataptr bc:size -- hl:handleptr 0E77: ; mem_stack_pop_data de:destptr -- 0E77: 0E77: ; mem_heap_to_stack [handle] -- {handle} 0E77: ; mem_stack_to_heap {handle} -- [handle] 0E77: 0E77: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0E77: ; Virtual Machine Opcodes 0E77: 0E77: ; v_mem_compact -- 0E77: ; v_mem_get_free -- 0E77: ; v_mem_get_free_total -- 0E77: 0E77: ; v_mem_get_address -- 0E77: ; v_mem_get_size -- 0E77: ; v_mem_get_address_for_index --
0E77: ; v_mem_get_index_for_address
-- 0E77: 0E77: ; v_mem_alloc -- 0E77: ; v_mem_dealloc -- 0E77: ; v_mem_new_handle -- 0E77: ; v_mem_save_data -- 0E77: ; v_mem_restore_data -- 0E77: 0E77: ; v_heap_alloc -- [handle] 0E77: ; v_heap_drop_handle [handle] -- 0E77: ; v_heap_new_handle -- [handle] 0E77: ; v_heap_get_handle [handle] -- [handle] 0E77: ; v_heap_push_data -- [handle] 0E77: ; v_heap_pop_data [handle] -- 0E77: 0E77: ; v_stack_alloc -- {handle} 0E77: ; v_stack_drop_handle {handle} -- 0E77: ; v_stack_new_handle -- {handle} 0E77: ; v_stack_get_handle {handle} -- {handle} 0E77: ; v_stack_pick_handle {handle_n .. handle1} -- 0E77: ; v_stack_push_data -- {handle} 0E77: ; v_stack_pop_data {handle} -- 0E77: ; v_stack_peek_handle -- {handle} 0E77: ; v_stack_poke_handle {handle} -- 0E77: 0E77: ; v_heap_to_stack [handle] -- {handle} 0E77: ; v_stack_to_heap {handle} -- [handle] 0E77: 0E77: 0E77: 0E77: 0E77: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0E77: 0E77: 0E77: 0E77: ; -------------------------------------------------------- 0E77: ; Initialize Memory Handler 0E77: ; 0E77: ; in: hl -> first usable byte 0E77: ; de -> behind last usable byte 0E77: ; out: -- 0E77: ; mod: af, bc, de, hl 0E77: 0E77: mem_init: 0E77: 22175B ld (mem_start),hl ; mem start = data start 0E7A: 22195B ld (mem_free_start),hl ; free start = data end 0E7D: 0E7D: EB ex hl,de 0E7E: CB85 res 0,l ; Handles auf gerade Adressen ausrichten 0E80: 0E80: 22255B ld (mem_end),hl ; mem end = stack end 0E83: 22235B ld (mem_stack_ptr),hl ; stack ptr := empty 0E86: 25 dec h ; 256 bytes for heap and stack 0E87: 0E87: 22215B ld (mem_heap_ptr),hl ; heap := empty 0E8A: 221F5B ld (mem_handles_end),hl ; heap start = handles end 0E8D: 221B5B ld (mem_handles_start),hl ; free end = handles start 0E90: 221D5B ld (mem_last_handle),hl 0E93: 0E93: 010000 ld bc,0 ; minimalen Speicherblock im Speicher anlegen. 0E96: C30810 jp mem_alloc ; => es ist immer ein Block in der Verwaltung. 0E99: ; -> Verwendung als Stopper zB. in mem_compact. 0E99: 0E99: 0E99: 0E99: ; -------------------------------------------------------- 0E99: ; Garbage Collection 0E99: ; 0E99: ; in: -- 0E99: ; out: -- 0E99: ; mod: -- 0E99: 0E99: v_mem_compact: 0E99: FDE5 push iy ; return address 0E9B: 0E9B: mem_compact: 0E9B: D7 rst save_registers 0E9C: F5 push af 0E9D: 0E9D: ; ----- Handles: ----- 0E9D: 0E9D: 3E00 ld a,black ; visual effect: border 0E9F: D3FE out ($fe),a 0EA1: 0EA1: ; handle-allocation-pointer zurücksetzen: 0EA1: 2A1F5B ld hl,(mem_handles_end) 0EA4: 221D5B ld (mem_last_handle),hl 0EA7: 0EA7: ; freie Handles am Anfang des Handles-Bereiches entfernen: 0EA7: EB ex hl,de ; de = mem_handles_end 0EA8: 2A1B5B ld hl,(mem_handles_start) 0EAB: 97 sub a 0EAC: 2B dec hl ; -> before_first_handle.hi 0EAD: 0EAD: 23 mc0 inc hl 0EAE: 23 inc hl 0EAF: BE cp (hl) ; handle.hi 0EB0: 28FB jr z,mc0 ; der ist auch noch frei 0EB2: 0EB2: 2B dec hl ; handle.lo 0EB3: 221B5B ld (mem_handles_start),hl ; hl -> 1st used handle 0EB6: 0EB6: ; ----- Datenblocks ----- 0EB6: 0EB6: 3E01 ld a,blue ; visual effect: border 0EB8: D3FE out ($fe),a 0EBA: 0EBA: ; 1. Schleife über alle handles: 0EBA: ; In allen belegten data.size wird ein rptr auf das handle 0EBA: ; und in das Handle die Länge aus data.size eingetragen. 0EBA: 0EBA: ; hl -> current handle ist da schon drin 0EBA: ; ld iy,(mem_handles_end) global handles und heap 0EBA: ; call mem_compact_loop1 werden in einem Durchlauf gemacht, 0EBA: ; weil sie direkt aneinander 0EBA: ; ld hl,(mem_heap_start) anschließen 0EBA: FD2A215B ld iy,(mem_heap_ptr) 0EBE: CDFD0E call mem_compact_loop1 0EC1: 0EC1: 2A235B ld hl,(mem_stack_ptr) 0EC4: FD2A255B ld iy,(mem_stack_end) 0EC8: CDFD0E call mem_compact_loop1 0ECB: 0ECB: ; 2. Schleife über alle Datenblöcke: 0ECB: ; Unbelegte Blöcke werden übersprungen, 0ECB: ; Belegte Blöcke werden bündig nach vorne angerückt, 0ECB: ; data.size wird restauriert und die Pointer in allen Handles aktualisiert. 0ECB: 0ECB: 3E02 ld a,red ; visual effect: border 0ECD: D3FE out ($fe),a 0ECF: 0ECF: 2A175B ld hl,(mem_data_start) ; hl -> old data 0ED2: 5D54 ld de,hl ; de -> new data 0ED4: FD2A195B ld iy,(mem_data_end) ; for loop end test 0ED8: CD260F call mem_compact_loop2 0EDB: 0EDB: ; update sysvar & exit 0EDB: ED53195B ld (mem_data_end),de 0EDF: 0EDF: CD7F0B call scr_restore_border ; clear visual effect, restore old border color 0EE2: F1 pop af 0EE3: C9 ret 0EE4: 0EE4: 0EE4: ; mem_compact_loop1: 0EE4: ; in der ersten Schleife über alle Handles wird in allen 0EE4: ; belegten data.size ein rptr auf das handle und in das handle 0EE4: ; die länge aus data.size eingetragen. 0EE4: ; Wenn mehrere Handles auf den gleichen Datenblock zeigen, 0EE4: ; wird eine Kette data.size->handle1->handle2->handle_n=data_size aufgebaut. 0EE4: ; 0EE4: ; in: hl -> first handle 0EE4: ; iy -> behind last handle 0EE4: ; out: hl = iy 0EE4: ; mod: af,bc,de,hl 0EE4: 0EE4: ; Lese Datenadresse aus dem Handle: 0EE4: 5E mc1 ld e,(hl) 0EE5: 23 inc hl 0EE6: 7E ld a,(hl) ; de -> data.size 0EE7: 23 inc hl ; hl -> next handle 0EE8: ; handle frei? -> loop 0EE8: ; freies handle => end-of-loop test nicht nötig: 0EE8: ; mem_handle_start..mem_handle_end: finales handle aus mem_init exisitiert immer 0EE8: ; stack und heap: Dürfen keine freigegebenen Handles enthalten. 0EE8: ; (wenn doch, dann muss das hier geändert werden.) 0EE8: A7 and a 0EE9: 28F9 jr z,mc1 0EEB: FE0E cp mem_empty_data>>8 0EED: 280E jr z,mc1e ; mem_empty_data liegt nicht im freien Speicher => nicht relozieren => skip 0EEF: 57 ld d,a 0EF0: 2B dec hl 0EF1: 2B dec hl ; hl -> handle 0EF2: 0EF2: ; Der aus dem Handle ausgelesene Wert muss jetzt folgendes sein: 0EF2: ; ptr -> data.size 0EF2: ; 0EF2: ; Der Wert in data.size kann folgendes sein: 0EF2: ; Block size => handle.ptr = data.size; data.size -> handle 0EF2: ; ptr -> other handle => handle.ptr -> other_handle; data.size -> handle 0EF2: 0EF2: ; get BC = data size or ptr to other handle from DE -> data.size 0EF2: ; store handle HL in data.size 0EF2: EB ex hl,de ; hl -> data.size.lo; de -> handle 0EF3: 4E ld c,(hl) 0EF4: 73 ld (hl),e 0EF5: 23 inc hl ; hl -> data.size.hi 0EF6: 46 ld b,(hl) ; bc = size or ptr to other handle 0EF7: 72 ld (hl),d 0EF8: EB ex hl,de ; hl -> handle 0EF9: 0EF9: ; speichere im Handle die Länge oder den Zeiger auf ein anderes Handle aus BC 0EF9: 71 ld (hl),c 0EFA: 23 inc hl ; hl -> handle.hi 0EFB: 70 ld (hl),b 0EFC: 23 inc hl ; hl -> next handle 0EFD: 0EFD: mem_compact_loop1: 0EFD: 0EFD: ; loop end test: 0EFD: FD7D mc1e ld a,yl ; mem_handles_end.lo 0EFF: BD cp l 0F00: 20E2 jr nz,mc1 0F02: FD7C ld a,yh ; mem_handles_end.hi 0F04: BC cp h 0F05: 20DD jr nz,mc1 0F07: C9 ret 0F08: 0F08: 0F08: ; mem_compact_loop2: 0F08: ; in der zweiten schleife über alle Datenblöcke werden freigegebene Blöcke, 0F08: ; erkennbar daran, dass in ihrem size-Feld kein rptr eingetragen wurde, 0F08: ; übersprungen. Alle benutzten Blöcke, erkennbar daran, dass sie jetzt im size-Feld 0F08: ; einen rptr auf ein Handle enthalten, erkennbar daran, dass die Blockgröße größer als 0F08: ; mem_max_size ist, werden bündig nach vorne geschoben, in das size-Feld 0F08: ; wieder die Länge eingetragen und in das Handle wieder ein Zeiger auf die neue 0F08: ; Position des Blocks. Zeigen mehrere Handles auf den Block, bilden sie eine verkettete 0F08: ; Liste: data.size->handle1->handle2->handle_n=data_size und werden alle korrigiert. 0F08: ; 0F08: ; in: hl -> old data 0F08: ; de -> new data 0F08: ; iy -> behind data end 0F08: ; out: hl -> old data end = iy 0F08: ; de -> new data end 0F08: ; mod: af,bc,de,hl 0F08: 0F08: ; get data.size: 0F08: 4E mc2 ld c,(hl) 0F09: 23 inc hl 0F0A: 46 ld b,(hl) ; bc = size or ptr -> handle 0F0B: 23 inc hl ; hl -> old_data.data 0F0C: 0F0C: ; data.size = size? => free block => skip 0F0C: 3E5F ld a,mem_max_hi-1 0F0E: B8 cp b 0F0F: 3014 jr nc,mc2ee ; => bc = size => free block => skip & loop 0F11: 0F11: ; block is in use: 0F11: ; bc -> handle 0F11: ; hl->old data.data 0F11: ; de->new data.size 0F11: 0F11: ; read bc = size (or ptr to other handle) from handle 0F11: ; write de = new data address into handle 0F11: ; if the read size is > mem_max_size, then this is a link to another handle. 0F11: ; Then do same with the other handle. 0F11: E5 push hl ; sp: -> old_data.data 0F12: 0F12: 6960 mc3 ld hl,bc ; hl -> handle.lo 0F14: 4E ld c,(hl) 0F15: 73 ld (hl),e 0F16: 23 inc hl ; hl -> handle.hi 0F17: 46 ld b,(hl) ; bc = value read from handle 0F18: 72 ld (hl),d ; store de -> new data.size in handle 0F19: B8 cp b ; mem_max_hi-1 - b 0F1A: 38F6 jr c,mc3 ; bc -> other handle 0F1C: ; das ausgelesene BC ist jetzt wirklich data_size. 0F1C: E1 pop hl ; hl -> old_data.data 0F1D: 0F1D: ; write bc = size to new data.size 0F1D: EB ex hl,de ; hl -> new data.size; de->old data.data 0F1E: 71 ld (hl),c 0F1F: 23 inc hl 0F20: 70 ld (hl),b ; new_data.size := size 0F21: 23 inc hl ; hl -> new_data.data 0F22: EB ex hl,de ; de -> new_data.data; hl -> old_data.data; bc = size > 0 0F23: 0F23: ; note: bc = size > 0 is guaranteed because we do not store 0-byte chunks 0F23: ; note: we also ldir the first chunks up to the first free chunk, though this is a nop. 0F23: ; but test for hl==de and adding bc to hl and de instead of ldir adds too much 0F23: ; overhead to each loop. 0F23: EDB0 ldir ; bc=0; de->new_data.end; hl->old_data.end 0F25: ;jr mc2e ((add hl,bc=0 is a nop)) 0F25: 0F25: 09 mc2ee add hl,bc ; skip old data for free block 0F26: 0F26: mem_compact_loop2: 0F26: 0F26: ; loop end test ; hl -> old data 0F26: ; de -> new data 0F26: FD7C mc2e ld a,yh ; mem_data_end.hi 0F28: BC cp h 0F29: 20DD jr nz,mc2 0F2B: FD7D ld a,yl ; mem_data_end.lo 0F2D: BD cp l 0F2E: 20D8 jr nz,mc2 0F30: C9 ret 0F31: 0F31: 0F31: 0F31: ; -------------------------------------------------------- 0F31: ; Get total amount of ultimately available memory 0F31: ; runs the garbage collection and 0F31: ; then returns the total amount of free ram. 0F31: ; note: there may be up to 4 bytes more availabe than returned. 0F31: ; 0F31: ; in: -- 0F31: ; out: hl = free memory size 0F31: ; nc & nz: hl>0 0F31: ; nc & z: hl=0; 0-byte request will work. 0F31: ; cy & z: hl=0; 0-byte request will fail. 0F31: ; mod: af, hl 0F31: 0F31: mem_get_free_total: 0F31: CD9B0E call mem_compact 0F34: ;jr mem_get_free 0F34: 0F34: 0F34: 0F34: ; -------------------------------------------------------- 0F34: ; Get amount of immediately available memory 0F34: ; which will not trigger the garbage collection. 0F34: ; note: there may be up to 4 bytes more availabe than returned. 0F34: ; 0F34: ; in: -- 0F34: ; out: hl = immediately available memory size 0F34: ; nc & nz: hl>0 0F34: ; nc & z: hl=0; 0 bytes immediately available. 0F34: ; cy & z: hl=0; even a 0-byte request will trigger mem_compact. 0F34: ; mod: af, hl 0F34: 0F34: mem_get_free: 0F34: D5 push de 0F35: 0F35: 2A1B5B ld hl,(mem_free_end) 0F38: ED5B195B ld de,(mem_free_start) 0F3C: 0F3C: 2B dec hl ; -2 for data.size 0F3D: 2B dec hl 0F3E: 2B dec hl ; -2 for handle 0F3F: 37 scf 0F40: 0F40: ED52 sbc hl,de 0F42: 0F42: D1 pop de 0F43: D0 ret nc ; z or nz 0F44: 0F44: ; less than 0 bytes free: 0F44: 24 inc h ; h = 0 & z 0F45: 6C ld l,h ; hl = 0 0F46: C9 ret ; z & cy 0F47: 0F47: 0F47: 0F47: ; -------------------------------------------------------- 0F47: ; Get data address and size for handle. 0F47: ; 0F47: ; in: hl -> handle 0F47: ; out: hl -> data 0F47: ; bc = size 0F47: ; mod: a, bc, hl 0F47: 0F47: mem_get_size_and_address: 0F47: 7E ld a,(hl) 0F48: 23 inc hl 0F49: 66 ld h,(hl) 0F4A: 6F ld l,a ; hl -> data.size 0F4B: 4E ld c,(hl) 0F4C: 23 inc hl 0F4D: 46 ld b,(hl) ; bc = size 0F4E: 23 inc hl ; hl -> data.data 0F4F: C9 ret 0F50: 0F50: 0F50: ; -------------------------------------------------------- 0F50: ; Get data address and size from handle. 0F50: ; 0F50: ; in: hl -> handle 0F50: ; out: hl -> data 0F50: ; de = size 0F50: ; mod: a, de, hl 0F50: 0F50: v_mem_get_size: ; -- 0F50: EB ex hl,de 0F51: FDE5 push iy 0F53: 0F53: mem_get_size_de_and_address: 0F53: 5E ld e,(hl) 0F54: 23 inc hl 0F55: 56 ld d,(hl) ; de -> data.size 0F56: EB ex hl,de ; hl -> data.size 0F57: 5E ld e,(hl) 0F58: 23 inc hl 0F59: 56 ld d,(hl) ; de = size 0F5A: 23 inc hl ; hl -> data.data 0F5B: C9 ret 0F5C: 0F5C: 0F5C: 0F5C: ; -------------------------------------------------------- 0F5C: ; Get data address for handle. 0F5C: ; 0F5C: ; in: hl -> handle 0F5C: ; out: hl -> data 0F5C: ; mod: a, hl 0F5C: 0F5C: mem_get_address: 0F5C: 7E ld a,(hl) 0F5D: 23 inc hl 0F5E: 66 ld h,(hl) 0F5F: 6F ld l,a 0F60: 23 inc hl 0F61: 23 inc hl 0F62: C9 ret 0F63: 0F63: 0F63: ; -------------------------------------------------------- 0F63: ; Get data size for handle. 0F63: ; 0F63: ; in: hl -> handle 0F63: ; out: bc = size 0F63: ; mod: a, bc 0F63: 0F63: mem_get_size: 0F63: E5 push hl 0F64: 7E ld a,(hl) 0F65: 23 inc hl 0F66: 66 ld h,(hl) 0F67: 6F ld l,a ; hl -> data.size 0F68: 4E ld c,(hl) 0F69: 23 inc hl 0F6A: 46 ld b,(hl) 0F6B: E1 pop hl ; handle 0F6C: C9 ret 0F6D: 0F6D: 0F6D: 0F6D: ; ---------------------------------------------------- 0F6D: ; Get address for index 0F6D: ; 0F6D: ; in: hl = handle 0F6D: ; de = index 0F6D: ; out: hl = address 0F6D: ; mod: af, hl 0F6D: 0F6D: mem_get_address_for_index: 0F6D: CD5C0F call mem_get_address 0F70: 19 add hl,de 0F71: C9 ret 0F72: 0F72: 0F72: ; ---------------------------------------------------- 0F72: ; Get index for address 0F72: ; 0F72: ; in: hl = handle 0F72: ; de = address 0F72: ; out: de = index 0F72: ; mod: af, de 0F72: 0F72: v_mem_get_index_for_address: ;
-- 0F72: E1 pop hl 0F73: FDE5 push iy 0F75: 0F75: mem_get_index_for_address: 0F75: E5 push hl 0F76: CD5C0F call mem_get_address 0F79: EB ex hl,de 0F7A: A7 and a 0F7B: ED52 sbc hl,de 0F7D: E1 pop hl 0F7E: C9 ret 0F7F: 0F7F: 0F7F: 0F7F: ; -------------------------------------------------------- 0F7F: ; UP: Test whether BC bytes are available. 0F7F: ; runs the garbage collection if required. 0F7F: ; aborts if not available. 0F7F: ; 0F7F: ; mem_assert_free: only checks for enough free memory 0F7F: ; mem_assert_size: also checks for a valid requested size 0F7F: ; 0F7F: ; in: bc = requested size 0F7F: ; out -- 0F7F: ; mod: af, hl 0F7F: 0F7F: mem_assert_size: 0F7F: 3E5F ld a,mem_max_hi-1 0F81: B8 cp b 0F82: 380C jr c,mas0 ; bc > mem_max => error => abort 0F84: 0F84: mem_assert_free: 0F84: CD340F call mem_get_free ; -> nc/cy, z/nz, hl >= 0 0F87: ED42 sbc hl,bc ; -> nc/cy 0F89: D0 ret nc ; passt ohne garbage collection 0F8A: 0F8A: CD310F call mem_get_free_total ; -> hl, c|cy 0F8D: ED42 sbc hl,bc ; 0F8F: D0 ret nc ; jetzt passt's 0F90: 0F90: C3B718 mas0 jp abort_oomem 0F93: 0F93: 0F93: 0F93: ; ---------------------------------------- 0F93: ; Pop Handle from Heap 0F93: ; 0F93: ; in: -- 0F93: ; out: hl -> handle **unprotected!** 0F93: ; mod: hl 0F93: 0F93: v_heap_drop_handle: ; [handle] -- 0F93: FDE5 push iy 0F95: 0F95: mem_heap_pop_handle: 0F95: 2A215B ld hl,(mem_heap_ptr) 0F98: 2B dec hl 0F99: 2B dec hl 0F9A: 22215B ld (mem_heap_ptr),hl 0F9D: C9 ret 0F9E: 0F9E: 0F9E: ; -------------------------------------------------------- 0F9E: ; Get top handle on heap 0F9E: ; 0F9E: ; in: -- 0F9E: ; out: hl -> handle 0F9E: ; mod: hl 0F9E: 0F9E: v_heap_get_handle: ; [handle] -- [handle] 0F9E: FDE5 push iy 0FA0: 0FA0: mem_heap_get_handle: 0FA0: 2A215B ld hl,(mem_heap_ptr) 0FA3: 2B dec hl 0FA4: 2B dec hl 0FA5: C9 ret 0FA6: 0FA6: 0FA6: ; ---------------------------------------- 0FA6: ; Pop Handle from Stack 0FA6: ; 0FA6: ; in: -- 0FA6: ; out: hl -> handle **unprotected!** 0FA6: ; mod: hl 0FA6: 0FA6: v_stack_drop_handle: ; {handle} -- 0FA6: FDE5 push iy 0FA8: 0FA8: mem_stack_pop_handle: 0FA8: 2A235B ld hl,(mem_stack_ptr) 0FAB: 23 inc hl 0FAC: 23 inc hl 0FAD: 22235B ld (mem_stack_ptr),hl 0FB0: 2B dec hl 0FB1: 2B dec hl 0FB2: C9 ret 0FB3: 0FB3: 0FB3: ; -------------------------------------------------------- 0FB3: ; Get top handle on stack 0FB3: ; 0FB3: ; in: -- 0FB3: ; out: hl -> handle 0FB3: ; mod: hl 0FB3: 0FB3: mem_stack_get_handle: 0FB3: 2A235B ld hl,(mem_stack_ptr) 0FB6: C9 ret 0FB7: 0FB7: 0FB7: ; -------------------------------------------------------- 0FB7: ; Get a new, free handle on heap 0FB7: ; 0FB7: ; in: -- 0FB7: ; out: hl -> handle 0FB7: ; mod: hl 0FB7: 0FB7: mem_heap_new_handle: 0FB7: 2A215B ld hl,(mem_heap_ptr) ; allocate handle on heap 0FBA: 23 inc hl 0FBB: 3600 ld (hl),0 0FBD: 23 inc hl 0FBE: 22215B ld (mem_heap_ptr),hl 0FC1: 2B dec hl 0FC2: 2B dec hl 0FC3: C9 ret 0FC4: 0FC4: 0FC4: ; -------------------------------------------------------- 0FC4: ; Get a new, free handle on stack 0FC4: ; 0FC4: ; in: -- 0FC4: ; out: hl -> handle 0FC4: ; mod: hl 0FC4: 0FC4: mem_stack_new_handle: 0FC4: 2A235B ld hl,(mem_stack_ptr) 0FC7: 2B dec hl 0FC8: 3600 ld (hl),0 0FCA: 2B dec hl 0FCB: 22235B ld (mem_stack_ptr),hl 0FCE: C9 ret 0FCF: 0FCF: 0FCF: ; -------------------------------------------------------- 0FCF: ; Get a new, free handle 0FCF: ; 0FCF: ; in: -- 0FCF: ; out: hl -> handle 0FCF: ; mod: af, hl 0FCF: 0FCF: mem_new_handle: 0FCF: C5 push bc 0FD0: 010000 ld bc,0 0FD3: CD840F call mem_assert_free 0FD6: C1 pop bc 0FD7: D5 push de 0FD8: CDDD0F call mem_new_handle_quick 0FDB: D1 pop de 0FDC: C9 ret 0FDD: 0FDD: 0FDD: ; -------------------------------------------------------- 0FDD: ; Get a new, free handle 0FDD: ; note: 2 bytes free space must be checked beforehand! 0FDD: ; 0FDD: ; in: -- 0FDD: ; out: hl -> handle 0FDD: ; mod: af, de, hl 0FDD: 0FDD: mem_new_handle_quick: 0FDD: 97 sub a 0FDE: ED5B1B5B ld de,(mem_handles_start) 0FE2: 1B dec de 0FE3: 12 ld (de),a ; stopper.hi := 0 finales handle löschen 0FE4: 1B dec de ; de -> stopper = mem_handles_start -2 0FE5: 0FE5: 2A1D5B ld hl,(mem_last_handle) 0FE8: 2B mnh1 dec hl ; hl -> prev_handle.hi 0FE9: BE cp (hl) 0FEA: 2B dec hl ; hl -> handle.lo 0FEB: 20FB jr nz,mnh1 ; handle.hi != 0 => belegt 0FED: 0FED: ; free handle found: hl 0FED: 221D5B ld (mem_last_handle),hl ; update round robbin pointer 0FF0: ;and a 0FF0: ED52 sbc hl,de ; ist es der stopper? 0FF2: 19 add hl,de ; 0FF3: C0 ret nz ; nein 0FF4: 221B5B ld (mem_handles_start),hl ; ja => update mem_handles_start 0FF7: C9 ret 0FF8: 0FF8: 0FF8: 0FF8: ; -------------------------------------------------------- 0FF8: ; Allocate memory. 0FF8: ; Runs mem_compact if requested size is not immediately available. 0FF8: ; Aborts with Out-of-memory if after mem_compact is still not enough memory free. 0FF8: ; 0FF8: ; The memory is not cleared 0FF8: ; The maximum size for BC is mem_max_size-1. ($5FFF) 0FF8: ; If 0 bytes are requested, then a handle with a pointer to mem_empty_data is returned. 0FF8: ; 0FF8: ; mem_alloc: allocates a handle for global data 0FF8: ; mem_stack_alloc: allocates a handle on the stack for procedure local data 0FF8: ; mem_heap_alloc: allocates a handle on the heap for temporary data across procedures 0FF8: ; 0FF8: ; in: bc = requested size 0FF8: ; out: f: z: bc=0 0FF8: ; nz: bc>0 0FF8: ; hl -> handle 0FF8: ; de -> data 0FF8: ; bc = size (pres.) 0FF8: ; mod: af, de, hl 0FF8: 0FF8: mem_stack_alloc: 0FF8: CD7F0F call mem_assert_size ; check size & space 0FFB: CDC40F call mem_stack_new_handle ; allocate handle on stack 0FFE: 180E jr ma2 ; allocate data 1000: 1000: mem_heap_alloc: 1000: CD7F0F call mem_assert_size ; check size & space 1003: CDB70F call mem_heap_new_handle ; allocate handle on heap 1006: 1806 jr ma2 ; allocate data 1008: 1008: mem_alloc: 1008: CD7F0F call mem_assert_size ; check size bc & free space 100B: CDDD0F call mem_new_handle_quick ; hl -> free handle 100E: 100E: ; allocate data 100E: 78 ma2 ld a,b 100F: B1 or c 1010: 2815 jr z,ma3 ; return mem_empty_data for 0-byte request 1012: 1012: ED5B195B ld de,(mem_data_end) ; de -> my_data.size 1016: 73 ld (hl),e ; store data address in handle 1017: 23 inc hl 1018: 72 ld (hl),d 1019: 2B dec hl ; hl -> handle 101A: 101A: EB ex hl,de ; hl -> data.size; de->handle 101B: 71 ld (hl),c ; store size in data.size 101C: 23 inc hl 101D: 70 ld (hl),b 101E: 23 inc hl ; hl->data.data 101F: 101F: 09 add hl,bc ; hl->data.end 1020: 22195B ld (mem_data_end),hl 1023: ED42 sbc hl,bc ; hl->data.data 1025: 1025: EB ex hl,de ; hl -> handle; de -> data.data 1026: C9 ret ; nz 1027: 1027: ; return mem_empty_data for a 0 byte request 1027: 1027: mem_set_empty_data: 1027: 11750E ma3: ld de,mem_empty_data 102A: 73 ld (hl),e ; store data address in handle 102B: 23 inc hl 102C: 72 ld (hl),d 102D: 2B dec hl ; hl -> handle 102E: C9 ret ; z ; bc = 0 102F: 102F: 102F: 102F: ; --------------------------------------- 102F: ; Reserviere Speicher und speichere Daten darin 102F: ; 102F: ; mem_save_data: alloc with mem_alloc for global data 102F: ; mem_stack_push_data: alloc with mem_stack_alloc on stack 102F: ; mem_heap_push_data: alloc with mem_heap_alloc on heap 102F: ; 102F: ; in: hl -> source data 102F: ; bc = data size 102F: ; out: hl -> handle 102F: ; de -> data 102F: ; mod: af, de, hl 102F: 102F: mem_stack_push_data: 102F: E5 push hl 1030: CDF80F call mem_stack_alloc 1033: 180A jr msd1 1035: 1035: mem_heap_push_data_no_exx: 1035: mem_heap_push_data: 1035: E5 push hl 1036: CD0010 call mem_heap_alloc 1039: 1804 jr msd1 103B: 103B: mem_save_data: 103B: E5 push hl ; sp:sourceptr 103C: CD0810 call mem_alloc ; hl:handleptr de:destptr bc:size z|nz 103F: E3 msd1 ex hl,(sp) ; sp:handleptr; hl:sourceptr; de:destptr 1040: 1040: C5 push bc 1041: D5 push de 1042: C46210 call nz,ldir 1045: D1 pop de 1046: C1 pop bc 1047: 1047: E1 pop hl ; hl -> handle 1048: C9 ret 1049: 1049: 1049: 1049: ; ------------------------------------------------------------ 1049: ; Restore saved data and release handle. 1049: ; 1049: ; in: hl -> handle 1049: ; de -> dest. 1049: ; out: -- 1049: ; mod: af 1049: 1049: mem_restore_data: 1049: D7 rst save_registers 104A: CD5C10 call mem_copy_data_to_de ; handle hl -> addr de 104D: ;jr mem_dealloc 104D: 104D: 104D: ; -------------------------------------------------------- 104D: ; Release handle and data. 104D: ; 104D: ; in: hl -> handle 104D: ; out: -- 104D: ; mod: -- 104D: 104D: mem_dealloc: 104D: 23 inc hl 104E: 3600 ld (hl),0 ; handle.hi := 0 1050: 2B dec hl 1051: C9 ret 1052: 1052: 1052: ; ------------------------------------------------------------ 1052: ; Restore data from data on heap and pop handle. 1052: ; 1052: ; in: de -> dest. 1052: ; out: -- 1052: ; mod: af 1052: 1052: mem_heap_pop_data_no_exx: 1052: mem_heap_pop_data: 1052: D7 rst save_registers 1053: CD950F call mem_heap_pop_handle ; hl -> dropped handle 1056: 1804 jr mem_copy_data_to_de ; handle hl -> addr de 1058: 1058: 1058: ; ------------------------------------------------------------ 1058: ; Restore data from data on stack and pop handle. 1058: ; 1058: ; in: de -> dest. 1058: ; out: -- 1058: ; mod: af 1058: 1058: mem_stack_pop_data: 1058: D7 rst save_registers 1059: CDA80F call mem_stack_pop_handle ; hl -> dropped handle 105C: ;jr mem_copy_data_to_de ; handle hl -> addr de 105C: 105C: 105C: ; -------------------------------------------------------- 105C: ; UP: copy data from data for handle HL to destination DE 105C: ; 105C: ; in: hl -> handle 105C: ; de -> destination 105C: ; out: de -> behind destination 105C: ; mod: af, bc, de, hl 105C: 105C: mem_copy_data_to_de: 105C: CD470F call mem_get_size_and_address ; hl->data bc:size 105F: ;jr ldir_if_nz 105F: 105F: 105F: ; --------------------------------------------- 105F: ; UP: ldir if bc > 0 105F: ; 105F: ; in: bc, de, hl as for ldir 105F: ; out: bc, de, hl as after ldir 105F: ; mod: af, bc, de, hl 105F: 105F: ldir_if_nz: 105F: 78 ld a,b 1060: B1 or c 1061: C8 ret z 1062: EDB0 ldir: ldir 1064: C9 ret 1065: 1065: 1065: ; --------------------------------------------- 1065: ; move handle from heap to stack 1065: ; 1065: ; in: -- 1065: ; out: hl -> handle on stack 1065: ; mod: hl 1065: 1065: v_heap_to_stack: ; [handle] -- {handle} 1065: FDE5 push iy 1067: 1067: mem_heap_to_stack: 1067: CD950F call mem_heap_pop_handle 106A: ;jr mem_stack_push_handle 106A: 106A: 106A: ; --------------------------------------------- 106A: ; push a handle on the stack 106A: ; 106A: ; in: hl -> handle 106A: ; out: hl -> handle on stack 106A: ; mod: hl 106A: 106A: mem_stack_push_handle: 106A: D5 push de 106B: 5E ld e,(hl) 106C: 23 inc hl 106D: 56 ld d,(hl) ; de -> data.size 106E: 2A235B ld hl,(mem_stack_ptr) 1071: 2B dec hl 1072: 72 ld (hl),d 1073: 2B dec hl 1074: 73 ld (hl),e 1075: 22235B ld (mem_stack_ptr),hl 1078: D1 pop de 1079: C9 ret 107A: 107A: 107A: ; --------------------------------------------- 107A: ; move handle from stack to heap 107A: ; 107A: ; in: -- 107A: ; out: hl -> handle on heap 107A: ; mod: hl 107A: 107A: v_stack_to_heap: ; {handle} -- [handle] 107A: FDE5 push iy 107C: 107C: mem_stack_to_heap: 107C: CDA80F call mem_stack_pop_handle 107F: ;jr mem_heap_push_handle 107F: 107F: 107F: ; --------------------------------------------- 107F: ; push handle on heap 107F: ; 107F: ; in: hl -> handle 107F: ; out: hl -> handle on stack 107F: ; mod: hl 107F: 107F: mem_heap_push_handle: 107F: D5 push de 1080: 5E ld e,(hl) 1081: 23 inc hl 1082: 56 ld d,(hl) ; de -> data.size 1083: 2A215B ld hl,(mem_heap_ptr) 1086: 73 ld (hl),e 1087: 23 inc hl 1088: 72 ld (hl),d 1089: 23 inc hl 108A: 22215B ld (mem_heap_ptr),hl 108D: 2B dec hl 108E: 2B dec hl 108F: D1 pop de 1090: C9 ret 1091: 1091: 1091: ; --------------------------------------------- 1091: ; access handle at calculated offset in stack 1091: ; 1091: ; in: de = index in stack; 0=topmost 1091: ; out: hl -> handle 1091: ; mod: hl 1091: 1091: mem_stack_pick_handle: 1091: 2A235B ld hl,(mem_stack_ptr) 1094: 19 add hl,de 1095: 19 add hl,de 1096: C9 ret 1097: 1097: 1097: ; -------------------------------------------------------- 1097: ; Test whether HL is a handle 1097: ; checks only the range [handles_start ... [mem_stack_end 1097: ; does not check alignment or for a free handle 1097: ; 1097: ; in: hl -> handle 1097: ; out: f: nc:is handle; cy:no handle 1097: ; mod: f 1097: 1097: mem_is_handle: 1097: EB ex hl,de 1098: E5 push hl 1099: CD9F10 call mem_is_handle_de 109C: E1 pop hl 109D: EB ex hl,de 109E: C9 ret 109F: 109F: 109F: ; -------------------------------------------------------- 109F: ; Test whether DE is a handle 109F: ; checks only the range [handles_start ... [mem_stack_end 109F: ; does not check alignment or for free handle 109F: ; 109F: ; in: de -> handle 109F: ; out: f: nc:is handle; cy:no handle 109F: ; mod: f, hl 109F: 109F: mem_is_handle_de: 109F: 37 scf 10A0: 2A255B ld hl,(mem_stack_end) 10A3: ED52 sbc hl,de 10A5: D8 ret c 10A6: 10A6: 37 scf 10A7: 2A1B5B ld hl,(mem_handles_start) 10AA: ED52 sbc hl,de 10AC: 3F ccf 10AD: C9 ret 10AE: 10AE: 10AE: ; -------------------------------------------------------- 10AE: ; Release handle in DE 10AE: ; 10AE: ; in: de -> handle 10AE: ; out: -- 10AE: ; mod: af 10AE: 10AE: mem_dealloc_de: 10AE: 97 sub a 10AF: 13 inc de 10B0: 12 ld (de),a ; handle.hi := 0 10B1: 1B dec de 10B2: C9 ret 10B3: 10B3: 10B3: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10B3: ; Virtual Machine Opcodes 10B3: 10B3: v_mem_get_free: ; -- 10B3: CD340F call mem_get_free 10B6: D5 pdexjiy push de 10B7: EB ex hl,de 10B8: FDE9 jp (iy) 10BA: 10BA: v_mem_get_free_total: ; -- 10BA: CD310F call mem_get_free_total 10BD: 18F7 jr pdexjiy 10BF: 10BF: v_mem_get_address: ; -- 10BF: EB ex hl,de 10C0: CD5C0F call mem_get_address 10C3: EB ex hl,de 10C4: FDE9 jp (iy) 10C6: 10C6: v_mem_alloc: ; -- 10C6: C5 push bc 10C7: 4B42 ld bc,de 10C9: CD0810 call mem_alloc 10CC: EB xpbcjiy ex hl,de 10CD: C1 pop bc 10CE: FDE9 jp (iy) 10D0: 10D0: v_heap_alloc: ; -- [handle] 10D0: C5 push bc 10D1: 4B42 ld bc,de 10D3: CD0010 call mem_heap_alloc 10D6: 18F4 jr xpbcjiy 10D8: 10D8: v_stack_alloc: ; -- {handle} 10D8: C5 push bc 10D9: 4B42 ld bc,de 10DB: CDF80F call mem_stack_alloc 10DE: 18EC jr xpbcjiy 10E0: 10E0: v_mem_dealloc: ; -- 10E0: CD9F10 call mem_is_handle_de 10E3: D4AE10 call nc,mem_dealloc_de 10E6: D1 pop de 10E7: FDE9 jp (iy) 10E9: 10E9: v_mem_new_handle: ; -- 10E9: CDCF0F call mem_new_handle 10EC: 18C8 jr pdexjiy 10EE: 10EE: v_mem_save_data ; -- 10EE: E1 pop hl ; hl->data 10EF: C5 push bc ; pc 10F0: 4B42 ld bc,de ; bc=size 10F2: CD3B10 call mem_save_data ; hl->handle 10F5: 18D5 jr xpbcjiy 10F7: 10F7: v_mem_restore_data: ; -- 10F7: E1 pop hl 10F8: CD4910 call mem_restore_data 10FB: D1 pop de 10FC: FDE9 jp (iy) 10FE: 10FE: v_heap_new_handle: ; -- [handle] 10FE: CDB70F call mem_heap_new_handle 1101: 18B3 jr pdexjiy 1103: 1103: v_stack_new_handle ; -- {handle} 1103: CDC40F call mem_stack_new_handle 1106: 18AE jr pdexjiy 1108: 1108: v_stack_get_handle ; {handle} -- {handle} 1108: ;call mem_stack_get_handle 1108: 2A235B ld hl,(mem_stack_ptr) 110B: 18A9 jr pdexjiy 110D: 110D: v_heap_push_data: ; -- [handle] 110D: E1 pop hl ; hl->data 110E: C5 push bc ; pc 110F: 4B42 ld bc,de ; bc=size 1111: CD3510 call mem_heap_push_data 1114: C1 pbpdjiy pop bc ; pc 1115: D1 pop de ; top item 1116: FDE9 jp (iy) 1118: 1118: v_stack_push_data: ; -- {handle} 1118: E1 pop hl ; hl->data 1119: C5 push bc ; pc 111A: 4B42 ld bc,de ; bc=size 111C: CD2F10 call mem_stack_push_data 111F: 18F3 jr pbpdjiy 1121: 1121: v_heap_pop_data: ; [handle] -- 1121: CD5210 call mem_heap_pop_data 1124: D1 pop de 1125: FDE9 jp (iy) 1127: 1127: v_stack_pop_data: ; {handle} -- 1127: CD5810 call mem_stack_pop_data 112A: D1 pop de 112B: FDE9 jp (iy) 112D: 112D: v_stack_pick_handle: ; {handle_n .. handle1} -- 112D: CD9110 call mem_stack_pick_handle 1130: EB ex hl,de 1131: FDE9 jp (iy) 1133: 1133: v_stack_peek_handle: ; -- {handle} 1133: EB ex hl,de 1134: CD6A10 call mem_stack_push_handle 1137: D1 pop de 1138: FDE9 jp (iy) 113A: 113A: v_stack_poke_handle: ; {handle} -- 113A: C5 push bc 113B: CDA80F call mem_stack_pop_handle ; hl->handle 113E: 4E ld c,(hl) 113F: 23 inc hl 1140: 46 ld b,(hl) ; bc -> data.size 1141: EB ex hl,de ; hl->handle (dest.) 1142: 71 ld (hl),c 1143: 23 inc hl 1144: 70 ld (hl),b 1145: 18CD jr pbpdjiy 1147: 1147: v_mem_get_address_for_index: ; --
1147: E1 pop hl 1148: CD6D0F call mem_get_address_for_index 114B: EB ex hl,de 114C: FDE9 jp (iy) 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: 114E: ; ---------------------------------------------------- 114E: ; Concatenate two memory blocks 114E: ; 114E: ; the data from the 2nd block is appended to the first block. 114E: ; the two blocks are deallocated and the resulting block is returned. 114E: ; 114E: ; in: hl -> handle 1 114E: ; de -> handle 2 114E: ; out: hl -> handle 114E: ; mod: af,hl 114E: 114E: mem_cat: 114E: C5 push bc 114F: 114F: D5 push de ; handle2 1150: E5 push hl ; handle1 1151: 1151: EB ex hl,de 1152: CD630F call mem_get_size ; bc:len2 1155: 6960 ld hl,bc 1157: EB ex hl,de 1158: CD630F call mem_get_size ; bc:len1 115B: 09 add hl,bc 115C: 4D44 ld bc,hl 115E: CD0810 call mem_alloc ; hl:handle3; de:data3; bc:len3 1161: 1161: E3 ex hl,(sp) ; hl:handle1 1162: E5 push hl 1163: CD5C10 call mem_copy_data_to_de 1166: E1 pop hl 1167: CD4D10 call mem_dealloc 116A: E1 pop hl ; handle3 116B: 116B: E3 ex hl,(sp) ; hl:handle2 116C: E5 push hl 116D: CD5C10 call mem_copy_data_to_de 1170: E1 pop hl 1171: CD4D10 call mem_dealloc 1174: 1174: E1 pop hl ; hl:handle3 1175: C1 pop bc ; bc 1176: C9 ret 1177: 1177: 1177: 1177: 1177: 1177: 1177: 1177: 1177: ; -------------------------------------------------------- 1177: ; Duplicate data and return new handle for it. 1177: ; 1177: ; in: hl -> handle 1177: ; out: hl -> new handle 1177: ; mod: af, hl 1177: 1177: mem_dup: 1177: D5 push de 1178: C5 push bc 1179: 1179: CD470F call mem_get_size_and_address; hl:source; bc:size 117C: E5 push hl ; sp:source 117D: CD0810 call mem_alloc ; hl:handle; de:dest; z/nz 1180: E3 ex hl,(sp) ; sp:handle; hl:source 1181: C46210 call nz,ldir 1184: E1 pop hl ; hl:new handle 1185: 1185: C1 pop bc 1186: D1 pop de 1187: C9 ret 1188: 1188: mem_dup_to_stack: 1188: D5 push de 1189: C5 push bc 118A: 118A: CD470F call mem_get_size_and_address; hl:source; bc:size 118D: E5 push hl ; sp:source 118E: CDF80F call mem_stack_alloc ; hl:handle; de:dest; z/nz 1191: E3 ex hl,(sp) ; sp:handle; hl:source 1192: C46210 call nz,ldir 1195: E1 pop hl ; hl:new handle 1196: 1196: C1 pop bc 1197: D1 pop de 1198: C9 ret 1199: 1199: 1199: 1199: 1199: 1199: 1199: 1199: 1199: ; mem_grow grow block size 1199: ; 1199: ; mem_append append block 2 to block 1 1199: ; mem_duprange copy of a subrange in a new handle 1199: ; 1199: ; mem_split split block into two blocks 1199: 1199: 1199: 1199: 1199: 1199: 1199: 1199: ; -------------------------------------------------------- 1199: ; shrink block, left-aligned 1199: ; 1199: ; in: hl -> handle 1199: ; de = new size 1199: ; out: hl -> new handle 1199: ; mod: af, bc, de, hl 1199: 1199: mem_shrink: 1199: 010000 ld bc,0 ; bc=left index; de=right index 119C: 182D jr mem_subrange 119E: 119E: 119E: ; -------------------------------------------------------- 119E: ; shrink block, right-aligned 119E: ; 119E: ; in: hl -> handle 119E: ; de = new size 119E: ; out: hl -> new handle 119E: ; mod: af, bc, de, hl 119E: 119E: mem_rshrink: 119E: E5 push hl ; sp:handle 119F: 7E ld a,(hl) 11A0: 23 inc hl 11A1: 66 ld h,(hl) 11A2: 6F ld l,a 11A3: E5 push hl ; sp:->block.size 11A4: 7E ld a,(hl) 11A5: 23 inc hl 11A6: 66 ld h,(hl) 11A7: 6F ld l,a ; hl = block size 11A8: 11A8: A7 and a 11A9: ED52 sbc hl,de ; hl=blocksize-new size = left idx 11AB: 4D44 ld bc,hl 11AD: 11AD: 19 add hl,de ; hl = block size 11AE: 5D54 ld de,hl ; de = block size = right index 11B0: 1823 jr mem_sr 11B2: 11B2: 11B2: 11B2: ; -------------------------------------------------------- 11B2: ; crop block hl at address de 11B2: ; no error checking: 11B2: ; new block size must be ≥ 1 11B2: ; cropped gap size must be ≥2 11B2: ; 11B2: ; in: hl->handle 11B2: ; de=new size 11B2: ; out: hl->gap.data 11B2: ; de=gap.size 11B2: ; bc->block.data 11B2: ; mod: af, bc, de,hl 11B2: 11B2: mem_shrink_quick 11B2: 7E ld a,(hl) 11B3: 23 inc hl 11B4: 66 ld h,(hl) 11B5: 6F ld l,a ; hl->block.size 11B6: 11B6: ; in: hl->block.size 11B6: ; de=new size 11B6: ; out: hl->gap.data 11B6: ; de=gap size 11B6: ; bc->block.data 11B6: ; mod: af, bc, de,hl 11B6: 11B6: mem_shrink_hl_quick 11B6: 4E ld c,(hl) 11B7: 73 ld (hl),e 11B8: 23 inc hl 11B9: 46 ld b,(hl) ; bc = old block size 11BA: 72 ld (hl),d ; set new block size := de 11BB: 23 inc hl 11BC: E5 push hl ; sp:->block.data 11BD: 11BD: 6960 ld hl,bc 11BF: 37 scf 11C0: ED52 sbc hl,de 11C2: 2B dec hl ; hl=gap size-2 11C3: EB ex hl,de ; de=gap size-2; hl=new block size 11C4: 11C4: C1 pop bc ; bc->block data 11C5: 09 add hl,bc ; hl->gap.size 11C6: 73 ld (hl),e 11C7: 23 inc hl 11C8: 72 ld (hl),d ; set gap size 11C9: 23 inc hl 11CA: 11CA: C9 ret 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: 11CB: ; -------------------------------------------------------- 11CB: ; crop block at both ends [bc ... [de 11CB: ; 11CB: ; try to crop it in place 11CB: ; needs only allocate new block if cropped size = old size -1 11CB: ; nooeds only to copy data, if new block or left gap=1 or right gap=1. 11CB: ; 11CB: ; in: hl -> handle 11CB: ; bc = left index 11CB: ; de = right index 11CB: ; out: hl -> new handle 11CB: ; mod: af, bc, de, hl 11CB: 11CB: mem_subrange: 11CB: E5 push hl ; sp: handle 11CC: 7E ld a,(hl) 11CD: 23 inc hl 11CE: 66 ld h,(hl) 11CF: 6F ld l,a 11D0: E5 push hl ; sp:->block.size 11D1: 7E ld a,(hl) 11D2: 23 inc hl 11D3: 66 ld h,(hl) 11D4: 6F ld l,a ; hl = block size 11D5: 11D5: 97 mem_sr sub a 11D6: ED52 sbc hl,de ; hl=postgap size 11D8: EB ex hl,de ; de=postgap size 11D9: 19 add hl,de ; hl=total size 11DA: 3002 jr nc,msr1 11DC: 57 ld d,a 11DD: 5F ld e,a ; de = post gap size 11DE: 11DE: CB78 msr1 bit 7,b 11E0: 2802 jr z,msr2 11E2: 47 ld b,a 11E3: 4F ld c,a ; bc = pre gap size 11E4: 11E4: 37 msr2 scf 11E5: ED52 sbc hl,de 11E7: 3853 jr c,msr_0 ; new data size = 0 11E9: ED42 sbc hl,bc ; hl = new data size -1 11EB: 384F jr c,msr_0 ; new data size = 0 11ED: 23 inc hl ; hl = new data size & hl > 0 11EE: 11EE: 7A ld a,d 11EF: B0 or b 11F0: 2008 jr nz,msr3 11F2: 7B ld a,e 11F3: 81 add c 11F4: 3804 jr c,msr3 11F6: FE02 cp 2 11F8: 3847 jr c,msr_1 ; only one byte cropped => allocate new 11FA: 11FA: 0B msr3 dec bc 11FB: 1B dec de 11FC: 11FC: 78 ld a,b 11FD: B1 or c 11FE: 2825 jr z,msr_1_x ; pregap=1 => move down 1200: ; pregap=0 or ≥2 1200: 7A ld a,d 1201: B3 or e 1202: 2821 jr z,msr_x_1 ; postgap=1 => move down 1204: ; pregap=0 or ≥2 1204: ; postgap=0 or ≥2 1204: ; bc = pregap size-1 (incl.+2 for .size) 1204: ; de = postgap size-1 (incl.+2 for .size) 1204: ; hl = new data size (excl.+2 for .size) 1204: 0B msr5 dec bc ; bc = pregap size (excl.+2) (bc=-2 if no pregap) 1205: 1B dec de ; de = postgap size (excl.+2) (de=-2 if no postgap) 1206: 1206: E3 ex hl,(sp) ; sp:new data size; hl->pregap.size 1207: 1207: CB78 bit 7,b 1209: 2005 jr nz,msr6 120B: 71 ld (hl),c 120C: 23 inc hl 120D: 70 ld (hl),b ; store pregap size in pregap.size 120E: 23 inc hl 120F: 09 add hl,bc ; hl->new_data.size 1210: 1210: C1 msr6 pop bc ; bc=new_data.size 1211: E5 push hl ; sp:->new_data.size 1212: 71 ld (hl),c 1213: 23 inc hl 1214: 70 ld (hl),b 1215: 23 inc hl 1216: 09 add hl,bc ; hl->postgap.size 1217: 1217: CB7A bit 7,d 1219: 2003 jr nz,msr7 121B: 73 ld (hl),e 121C: 23 inc hl 121D: 72 ld (hl),d 121E: 121E: D1 msr7 pop de ; de->new_data.size 121F: E1 pop hl ; hl->handle 1220: 73 ld (hl),e 1221: 23 inc hl 1222: 72 ld (hl),d 1223: 2B dec hl 1224: C9 ret 1225: 1225: ; pregap=1 or postgap=1 => move down 1225: ; bc = pregap size-1 (incl.+2 for .size) 1225: ; de = postgap size-1 (incl.+2 for .size) 1225: ; hl = new data size (excl.+2 for .size) 1225: ; sp:->old_block.size 1225: msr_1_x ; pregap=1 => move down 1225: msr_x_1 ; postgap=1 => move down 1225: EB ex hl,de ; de=new data size 1226: 09 add hl,bc ; hl=old pregap size +old postgap size = new postgap size 1227: E3 ex hl,(sp) ; sp:new postgap size; hl->old_block.size 1228: 1228: 73 ld (hl),e 1229: 23 inc hl 122A: 72 ld (hl),d ; store new data size 122B: 23 inc hl ; hl->new data.data 122C: 122C: C5 push bc ; sp:pregap size-1 122D: 4B42 ld bc,de ; bc = new data size = ldir size 122F: D1 pop de ; de = pregap size -1 1230: 13 inc de ; de = pregap size 1231: EB ex hl,de ; de -> new data.data = ldir dest 1232: 19 add hl,de ; hl -> new data.data+pregap size = ldir source 1233: 1233: EDB0 ldir ; de->postgap.size 1235: 1235: EB ex hl,de ; hl->postgap.size 1236: C1 pop bc ; bc=new postgap size 1237: 71 ld (hl),c 1238: 23 inc hl 1239: 70 ld (hl),b 123A: 123A: E1 pop hl ; hl->handle 123B: C9 ret 123C: 123C: ; new datasize = 0 123C: 123C: E1 msr_0 pop hl ; drop ptr -> old data.size 123D: E1 pop hl ; hl->handle 123E: C32710 jp mem_set_empty_data 1241: 1241: ; new data size = old data size -1 1241: ; bc = pregap size (incl.+2 for .size) 1241: ; de = postgap size (incl.+2 for .size) uninteressant 1241: ; hl = new data size (excl.+2 for .size) 1241: ; sp: ->handle 1241: ; sp: ->data.size uninteressant, da mem_malloc mem_compact starten könnte 1241: msr_1 1241: D1 pop de ; drop ->data.size 1242: C5 push bc ; sp:pregap size 1243: 4D44 ld bc,hl ; bc=new data size 1245: CD7F0F call mem_assert_size 1248: D1 pop de ; de = pregap size 1249: E1 pop hl ; hl->old handle 124A: E5 push hl ; sp:->old handle 124B: 7E ld a,(hl) 124C: 23 inc hl 124D: 66 ld h,(hl) 124E: 6F ld l,a ; hl->old data 124F: 19 add hl,de ; hl=old data+pregap size = ldir src 1250: E5 push hl ; sp: -> ldir source 1251: 1251: CD0810 call mem_alloc ; hl->new handle; de->new data; bc=new data size 1254: E3 ex hl,(sp) ; sp:->new handle; hl->ldir src; de->new data=ldir dest; bc=ldir sz 1255: EDB0 ldir 1257: 1257: E1 pop hl ; new handle 1258: D1 pop de ; old handle 1259: C3AE10 jp mem_dealloc_de 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: 125C: ; ------------------------------------------------ 125C: ; validate index hl 125C: ; 125C: ; in: hl = index 125C: ; bc = size 125C: ; out: hl = adjusted index: [0..hl..bc] 125C: ; mod: af, hl 125C: 125C: mem_validate_hl_and_de 125C: EB ex hl,de 125D: CD6112 call mem_validate_index 1260: EB ex hl,de 1261: 1261: mem_validate_index 1261: 7C ld a,h 1262: 07 rlca 1263: 3807 jr c,vd1 ; hl < 0 1265: 1265: ;and a 1265: ED42 sbc hl,bc ; cp hl,bc 1267: 09 add hl,bc 1268: D8 ret c ; hl=bc => hl:=bc 126B: C9 ret 126C: 126C: 210000 vd1 ld hl,0 126F: C9 ret 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: 1270: #include "mem.ass" 1270: mempack_end equ $ 1270: 1270: vip_start equ $ 1270: 1270: 1270: ; -------------------------------------------- 1270: ; Virtual Machine 1270: ; -------------------------------------------- 1270: 1270: ; Start: rst vip 1270: ; Stop: defb to_real 1270: ; dispatcher entry: IY 1270: ; instruction pointer: BC 1270: ; return stack: SP 1270: ; data heap: SP (mixed with return addresses) 1270: ; top item of heap: DE 1270: ; local variables: IX 1270: 1270: 1270: v_scratch data 6 1270: 1270: 1270: ; ---------------------------------------- 1270: ; Init virtual machine 1270: ; 1270: 1270: init_vip: 1270: C9 ret 1271: 1271: 1271: 1271: ; ---------------------------------------- 1271: ; Switch to virtual 1271: ; 1271: ; RST entry 1271: ; 1271: ; in: de: top stack item 1271: ; out: de: top stack item 1271: ; mod: 1271: 1271: #if 0 1271: 1271: vip: pop bc ; bc = vip pc 1271: vip_iy: ; auxiliary entry 1271: ld iy,vip_dis ; vip dispatcher entry 1271: jp (iy) 1271: 1271: #endif 1271: 1271: 1271: 1271: ; ---------------------------------- 1271: ; virtual instruction processor 1271: ; program execution dispatcher 1271: 1271: 0A vip_dis ld a,(bc) 1272: 03 inc bc 1273: 2614 ld h,v_tab>>8 1275: 6F ld l,a 1276: E9 jp (hl) 1277: 1277: 1277: 1277: ; ------------------------------------- 1277: ; opcode implementations 1277: ; ------------------------------------- 1277: 1277: 1277: ; ------------------------------------- 1277: ; calculate unsigned maximum value 1277: ; umax -- 1277: 1277: E1 v_umax pop hl 1278: A7 and a 1279: ED52 vum1 sbc hl,de 127B: 38F4 jr c,vip_dis ; jp c,(iy) 127D: 19 add hl,de 127E: EB ex hl,de 127F: FDE9 jp (iy) 1281: 1281: ; ------------------------------------- 1281: ; calculate unsigned minimum value 1281: ; umin -- 1281: 1281: E1 v_umin pop hl 1282: A7 and a 1283: ED52 vum2 sbc hl,de 1285: 30EA jr nc,vip_dis ; jp c,(iy) 1287: 19 add hl,de 1288: EB ex hl,de 1289: FDE9 jp (iy) 128B: 128B: ; ------------------------------------- 128B: ; calculate signed maximum value 128B: ; max -- 128B: 128B: E1 v_max pop hl 128C: 7A ld a,d 128D: AC xor h 128E: F27912 jp p,vum1 1291: 18F0 jr vum2 1293: 1293: ; ------------------------------------- 1293: ; calculate signed minimum value 1293: ; min -- 1293: 1293: E1 v_min pop hl 1294: 7A ld a,d 1295: AC xor h 1296: F28312 jp p,vum2 1299: 18DE jr vum1 129B: 129B: ; ------------------------------------- 129B: ; execute next 1-byte opcode only if result is true 129B: ; else the opcode is skipped 129B: ; if -- 129B: 129B: 7A v_if ld a,d 129C: B3 or e 129D: D1 pop de 129E: 2810 jr z,skip1 12A0: FDE9 jp (iy) 12A2: 12A2: ; ------------------------------------- 12A2: ; execute next 2-byte opcode only if result is true 12A2: ; else the opcode is skipped 12A2: ; iff -- 12A2: 12A2: 7A v_iff ld a,d 12A3: B3 or e 12A4: D1 pop de 12A5: 2808 jr z,skip2 12A7: FDE9 jp (iy) 12A9: 12A9: ; ------------------------------------- 12A9: ; execute next 3-byte opcode only if result is true 12A9: ; else the opcode is skipped 12A9: ; ifff -- 12A9: 12A9: 7A v_ifff ld a,d 12AA: B3 or e 12AB: D1 pop de 12AC: 20C3 jr nz,vip_dis 12AE: 03 skip3 inc bc 12AF: 03 skip2 inc bc 12B0: 03 skip1 inc bc 12B1: FDE9 jp (iy) 12B3: 12B3: ; ------------------------------------- 12B3: ; push immediate byte sign extended 12B3: ; byte -- 12B3: 12B3: D5 v_byte push de 12B4: 0A ld a,(bc) 12B5: 03 inc bc 12B6: FE db $fe ; cp a,N 12B7: ;jr bp1 12B7: 12B7: ; ------------------------------------- 12B7: ; peek byte sign extended 12B7: ;
peekb -- 12B7: 12B7: 1A v_peekb ld a,(de) 12B8: 12B8: 5F bp1 ld e,a 12B9: 87 add a 12BA: 9F sbc a 12BB: 57 ld d,a 12BC: FDE9 jp (iy) 12BE: 12BE: ; ------------------------------------- 12BE: ; push immediate word 12BE: ; push -- 12BE: 12BE: v_number 12BE: D5 push de 12BF: 0A ld a,(bc) 12C0: 03 inc bc 12C1: 5F ld e,a 12C2: 0A ld a,(bc) 12C3: 03 inc bc 12C4: 57 ld d,a 12C5: FDE9 jp (iy) 12C7: 12C7: ; ------------------------------------- 12C7: ; peek word 12C7: ;
peek -- 12C7: 12C7: EB v_peek ex hl,de 12C8: 5E ld e,(hl) 12C9: 23 inc hl 12CA: 56 ld d,(hl) 12CB: FDE9 jp (iy) 12CD: 12CD: ; ------------------------------------- 12CD: ; poke word 12CD: ;
poke -- 12CD: 12CD: EB v_poke ex hl,de 12CE: D1 pop de 12CF: 73 ld (hl),e 12D0: 23 inc hl 12D1: 72 ld (hl),d 12D2: D1 pop de 12D3: FDE9 jp (iy) 12D5: 12D5: ; ------------------------------------- 12D5: ; poke byte 12D5: ;
pokeb -- 12D5: 12D5: EB v_pokeb ex hl,de 12D6: D1 pop de 12D7: 73 ld (hl),e 12D8: D1 pop de 12D9: FDE9 jp (iy) 12DB: 12DB: ; ------------------------------------- 12DB: ; duplicate 2nd on stack value 12DB: ; over -- 12DB: 12DB: E1 v_over pop hl 12DC: E5 push hl 12DD: D5 push de 12DE: EB ex hl,de 12DF: FDE9 jp (iy) 12E1: 12E1: ; ------------------------------------- 12E1: ; duplicate value from stack by index 12E1: ; ... pick -- ... 12E1: 12E1: EB v_pick ex hl,de 12E2: 2B dec hl 12E3: 29 add hl,hl 12E4: 39 add hl,sp 12E5: 5E ld e,(hl) 12E6: 23 inc hl 12E7: 56 ld d,(hl) 12E8: FDE9 jp (iy) 12EA: 12EA: ; ------------------------------------- 12EA: ; Set bit [15=left..0=right] 12EA: ; setbit -- 12EA: 12EA: v_setbit 12EA: 7B ld a,e 12EB: CD0821 call calc_bmask 12EE: CB5B bit 3,e 12F0: D1 pop de 12F1: 2004 jr nz,vsb1 12F3: B3 or e 12F4: 5F ld e,a 12F5: FDE9 jp (iy) 12F7: B2 vsb1 or d 12F8: 57 ld d,a 12F9: FDE9 jp (iy) 12FB: 12FB: ; ------------------------------------- 12FB: ; clear bit [15=left..0=right] 12FB: ; clrbit -- 12FB: 12FB: v_clrbit 12FB: 7B ld a,e 12FC: CD1421 call calc_nmask 12FF: CB5B bit 3,e 1301: D1 pop de 1302: 2004 jr nz,vcb1 1304: A3 and e 1305: 5F ld e,a 1306: FDE9 jp (iy) 1308: A2 vcb1 and d 1309: 57 ld d,a 130A: FDE9 jp (iy) 130C: 130C: ; ------------------------------------- 130C: ; jump to address 130C: ; jump
-- 130C: 130C: 6960 v_jump ld hl,bc 130E: 4E ld c,(hl) 130F: 23 inc hl 1310: 46 ld b,(hl) 1311: FDE9 jp (iy) 1313: 1313: ; ------------------------------------- 1313: ; branch to address at offset 1313: ; the offset is based to the address of the 'bra' opcode 1313: ; bra -- 1313: 1313: 0A v_bra ld a,(bc) ; offset 1314: 0B dec bc ; pc back to opcode 1315: 6F ld l,a ; l=a 1316: 87 add a ; cy=vz 1317: 9F sbc a ; sign extend 1318: 67 ld h,a ; hl=offset 1319: 09 add hl,bc ; hl=new pc 131A: 4D44 ld bc,hl ; jump 131C: FDE9 jp (iy) 131E: 131E: ; ------------------------------------- 131E: ; branch to address at offset if condition is true 131E: ; the offset is based to the address of the 'bra_if' opcode 131E: ; bra_if -- 131E: 131E: v_bra_if 131E: 7A ld a,d 131F: B3 or e 1320: D1 pop de 1321: 20F0 jr nz,v_bra 1323: 03 inc bc 1324: FDE9 jp (iy) 1326: 1326: ; ------------------------------------- 1326: ; branch to address at offset if condition is true 1326: ; the offset is based to the address of the 'bra_if' opcode 1326: ; bra_ifnot -- 1326: 1326: v_bra_ifnot 1326: 7A ld a,d 1327: B3 or e 1328: D1 pop de 1329: 28E8 jr z,v_bra 132B: 03 inc bc 132C: FDE9 jp (iy) 132E: 132E: ; ------------------------------------- 132E: ; execute vip opcode at address 132E: ; may be used to execute machine code sub routines 132E: ; which conform, especially on exit, to the vip opcode interface: 132E: ; de = top stack item 132E: ; bc = pc 132E: ; iy = vip_dis 132E: ; return with 'jp (iy)' or 'jp vip_iy' or 'jp vip' 132E: ; 132E: ; opcode
-- 132E: 132E: v_opcode: 132E: 0A ld a,(bc) 132F: 03 inc bc 1330: 6F ld l,a 1331: 0A ld a,(bc) 1332: 03 inc bc 1333: 67 ld h,a 1334: E9 jp (hl) 1335: 1335: ; ------------------------------------- 1335: ; call a vip procedure 1335: ; arguments and return value depend on called procedure. 1335: ; it is recommended that the called procedure uses 'penter' and 'pexit' or 'preturn'. 1335: ; else it must cope with the return address on the stack. 1335: ; 1335: ; [,..] call
-- [] 1335: 1335: D5 v_call push de ; push top value 1336: 6960 ld hl,bc 1338: 4E ld c,(hl) 1339: 23 inc hl 133A: 46 ld b,(hl) ; bc = pc = procedure address 133B: 23 inc hl 133C: EB ex hl,de ; top value = return address 133D: FDE9 jp (iy) 133F: 133F: ; ------------------------------------- 133F: ; return from procedure without local variables. 133F: ; Notes: do not use 'penter'. 133F: ; the top value after procedure entry is the return address! 133F: ; you cannot manage local variables with lvar. 133F: ; keep track of the stack contents. 133F: ; remove all arguements before returning. 133F: ; put the return address on top of the stack! 133F: ; exit with 'exit' if you don't return a value, 133F: ; else push the return value and exit with 'return'. 133F: ; 'exit' and 'jp_calc' are effectively the same. 133F: ; 'exit' can be substituted with 'swap' + 'return'. 133F: ; 133F: ; return a return value: 133F: ; return -- 133F: ; return nothing: 133F: ; exit -- 133F: 133F: ;v_return 133F: ; pop bc 133F: ; jp (iy) 133F: 133F: ; ------------------------------------- 133F: ; jump to calculated address 133F: ; 'exit' and 'jp_calc' are effectively the same. 133F: ;
jp_calc -- 133F: 133F: v_jp_calc 133F: 4B42 v_exit ld bc,de 1341: D1 pop de 1342: FDE9 jp (iy) 1344: 1344: ; ------------------------------------- 1344: ; call procedure at calculated address 1344: ;
call_calc -- 1344: 1344: v_call_calc 1344: E1 pop hl ; new top 1345: C5 push bc ; push ret addr 1346: 4B42 ld bc,de ; pc := top 1348: EB ex hl,de ; top := new top 1349: FDE9 jp (iy) 134B: 134B: ; ---------------------------------------- 134B: ; procedures with local variables 134B: ; 134B: ; procedure entry: 134B: ; allocate local variables on stack: 134B: ; 134B: ; penter 134B: ; tells how many variables to allocate on the stack. 134B: ; e.g. allocate 5 local variables with: penter 5. 134B: ; 134B: ; access function arguments: 134B: ; lvar 2 (last argument) 134B: ; lvar 3 (last but one argument) 134B: ; 134B: ; access local variables: 134B: ; lvar -1 (first local var) 134B: ; lvar -2 (2nd local var) 134B: ; 134B: ; access what you better don't access: 134B: ; lvar 0 old ix 134B: ; lvar 1 return address 134B: ; 134B: ; procedure exit: 134B: ; close local variables & return: 134B: ; 134B: ; pexit 134B: ; tells how many arguments to remove from stack. 134B: ; e.g. if the function took 3 arguments then exit with: pexit 3. 134B: ; 134B: ; preturn 134B: ; same as pexit, but returns a return value . 134B: 134B: ; ---------------------------------------- 134B: ; procedure entry: 134B: ; [,...] penter -- 134B: 134B: v_penter 134B: E1 pop hl ; ret addr 134C: 134C: D5 push de ; top item 134D: E5 push hl ; ret addr 134E: DDE5 push ix ; old ix 1350: 1350: DD210000 ld ix,0 1354: DD39 add ix,sp ; new ix -> old ix 1356: 1356: 0A ld a,(bc) 1357: 03 inc bc 1358: 87 add a ; x2 1359: ED44 neg 135B: 6F ld l,a 135C: 9F sbc a ; $00 for n=0 and $FF for n>0 135D: 67 ld h,a 135E: 39 add hl,sp 135F: F9 ld sp,hl 1360: 1360: D1 pop de 1361: ; note: DE wird von einem ansonsten leeren Stack gepoppt: 1361: ; DE enthält jetzt den Wert der letzten lokalen Variablen. 1361: ; Diese wird wieder mit DE überschrieben, sobald der erste Wert auf den Stack gepusht wird. 1361: ; Das ist ungefährlich, weil sich eine lokalte Variable nicht ändern kann, solange der 1361: ; Stack leer ist. Um die lokale Variable zu ändern, müssen neuer Wert und Adresse auf den 1361: ; Stack gepusht werden => derweil ist die gefährdete lokale Variable nicht mehr in DE! 1361: FDE9 jp (iy) 1363: 1363: ; ---------------------------------------- 1363: ; exit from procedure returning a value 1363: ; preturn -- 1363: 1363: v_preturn 1363: DDF9 ld sp,ix ; discard local variables 1365: DDE1 pop ix ; old ix 1367: 1367: 0A ld a,(bc) ; arguments to discard 1368: C1 pop bc ; bc = ret addr 1369: 1369: 87 add a ; bytes to discard 136A: 6F ld l,a 136B: 2600 ld h,0 ; sign extend 136D: 39 add hl,sp 136E: F9 ld sp,hl ; discard arguments 136F: 136F: ;ld de,de ; return value is already in de 136F: FDE9 jp (iy) 1371: 1371: ; ---------------------------------------- 1371: ; exit from procedure returning nothing 1371: ; pexit -- 1371: 1371: FD217713 v_pexit ld iy,pex1 1375: 18EC jr v_preturn 1377: D1 pex1 pop de 1378: C32100 jp vip_iy 137B: 137B: ; ---------------------------------------- 137B: ; Get address of local variable 137B: ; lvar --
137B: 137B: D5 v_lvar push de 137C: 0A ld a,(bc) 137D: 03 inc bc 137E: 137E: DD54 ld d,xh 1380: DD5D ld e,xl 1382: 87 add a ; x2 & cy=vz 1383: 6F ld l,a ; l=offset 1384: 9F sbc a ; sign extend 1385: 67 ld h,a ; hl=offset 1386: 19 add hl,de ; hl=ix+offset 1387: 1387: EB ex hl,de 1388: FDE9 jp (iy) 138A: 138A: ; ---------------------------------------- 138A: ; Store value in local variable 138A: ; lvar_poke -- 138A: 138A: v_lvar_poke 138A: 0A ld a,(bc) 138B: 03 inc bc 138C: 138C: DD54 ld d,xh 138E: DD5D ld e,xl 1390: 87 add a ; x2 & cy=vz 1391: 6F ld l,a ; l=offset 1392: 9F sbc a ; sign extend 1393: 67 ld h,a ; hl=offset 1394: 19 add hl,de ; hl=ix+offset 1395: 1395: D1 pop de ; de=value 1396: 73 ld (hl),e 1397: 23 inc hl 1398: 72 ld (hl),d 1399: 1399: D1 pop de 139A: FDE9 jp (iy) 139C: 139C: ; ------------------------------------- 139C: ; increment variable at given address 139C: ;
pp -- 139C: 139C: EB v_pp ex hl,de 139D: 34 inc (hl) 139E: 2002 jr nz,$+4 13A0: 23 inc hl 13A1: 34 inc (hl) 13A2: D1 pop de ; pop de erst zum schluss, falls der stack leer ist 13A3: FDE9 jp (iy) ; und pp die letzte lokale Variable incrementiert 13A5: 13A5: ; ------------------------------------- 13A5: ; decrement variable at given address 13A5: ;
mm -- 13A5: 13A5: EB v_mm ex hl,de 13A6: 7E ld a,(hl) 13A7: 35 dec (hl) 13A8: A7 and a 13A9: 2002 jr nz,$+4 13AB: 23 inc hl 13AC: 35 dec (hl) 13AD: D1 pop de ; pop de erst zum schluss, falls der stack leer ist 13AE: FDE9 jp (iy) ; und mm die letzte lokale Variable decrementiert 13B0: 13B0: ; ------------------------------------- 13B0: ; increment and then peek variable at given address 13B0: ;
pp_peek -- 13B0: 13B0: v_pp_peek 13B0: EB ex hl,de 13B1: 5E ld e,(hl) 13B2: 23 inc hl 13B3: 56 ld d,(hl) 13B4: 13 inc de 13B5: 72 ld (hl),d 13B6: 2B dec hl 13B7: 73 ld (hl),e 13B8: FDE9 jp (iy) 13BA: 13BA: ; ------------------------------------- 13BA: ; decrement and then peek variable at given address 13BA: ;
mm_peek -- 13BA: 13BA: v_mm_peek 13BA: EB ex hl,de 13BB: 5E ld e,(hl) 13BC: 23 inc hl 13BD: 56 ld d,(hl) 13BE: 1B dec de 13BF: 72 ld (hl),d 13C0: 2B dec hl 13C1: 73 ld (hl),e 13C2: FDE9 jp (iy) 13C4: 13C4: ; ------------------------------------- 13C4: ; peek and then increment variable at given address 13C4: ;
peek_pp -- 13C4: 13C4: v_peek_pp 13C4: EB ex hl,de 13C5: 5E ld e,(hl) 13C6: 23 inc hl 13C7: 56 ld d,(hl) 13C8: 13 inc de 13C9: 72 ld (hl),d 13CA: 2B dec hl 13CB: 73 ld (hl),e 13CC: 1B dec de 13CD: FDE9 jp (iy) 13CF: 13CF: ; ------------------------------------- 13CF: ; peek and then increment variable at given address 13CF: ;
peek_mm -- 13CF: 13CF: v_peek_mm 13CF: EB ex hl,de 13D0: 5E ld e,(hl) 13D1: 23 inc hl 13D2: 56 ld d,(hl) 13D3: 1B dec de 13D4: 72 ld (hl),d 13D5: 2B dec hl 13D6: 73 ld (hl),e 13D7: 13 inc de 13D8: FDE9 jp (iy) 13DA: 13DA: ; ------------------------------------- 13DA: ; bitwise boolean and 13DA: ; may be used for masking arbitrary values 13DA: ; or for 'and'ing boolean values (boolean: 0 and 1 only) 13DA: ; if used in a boolean sense on arbitrary values 13DA: ; the result will not be as desired, 13DA: ; and -- 13DA: 13DA: E1 v_and pop hl 13DB: 7C ld a,h 13DC: A2 and d 13DD: 57 ld d,a 13DE: 7D ld a,l 13DF: A3 and e 13E0: 5F ld e,a 13E1: FDE9 jp (iy) 13E3: 13E3: ; ------------------------------------- 13E3: ; bitwise boolean or 13E3: ; or -- 13E3: 13E3: E1 v_or pop hl 13E4: 7C ld a,h 13E5: B2 or d 13E6: 57 ld d,a 13E7: 7D ld a,l 13E8: B3 or e 13E9: 5F ld e,a 13EA: FDE9 jp (iy) 13EC: 13EC: ; ------------------------------------- 13EC: ; bitwise boolean xor 13EC: ; or -- 13EC: 13EC: E1 v_xor pop hl 13ED: 7C ld a,h 13EE: AA xor d 13EF: 57 ld d,a 13F0: 7D ld a,l 13F1: AB xor e 13F2: 5F ld e,a 13F3: FDE9 jp (iy) 13F5: 13F5: 13F5: ; ------------------------------------- 13F5: ; Dispatcher table 13F5: ; ------------------------------------- 13F5: 13F5: FFFFFFFF 13F9: FFFFFFFF 13FD: FFFFFF defs 255 - ($-1)%256 1400: v_tab 1400: 1400: byte equ $-v_tab 1400: C3B312 jp v_byte 1403: 1403: number equ $-v_tab 1403: C3BE12 jp v_number 1406: 1406: ;hpush equ $-v_tab 1406: ; jp v_hpush 1406: 1406: hpeek equ $-v_tab 1406: C35D16 jp v_hpeek 1409: 1409: ;hpop equ $-v_tab 1409: ; jp v_hpop 1409: 1409: mult equ $-v_tab 1409: C3A815 jp v_mult 140C: 140C: div equ $-v_tab 140C: C3D215 jp v_div 140F: 140F: rem equ $-v_tab 140F: C3E115 jp v_rem 1412: 1412: peek equ $-v_tab 1412: C3C712 jp v_peek 1415: 1415: peekb equ $-v_tab 1415: C3B712 jp v_peekb 1418: 1418: poke equ $-v_tab 1418: C3CD12 jp v_poke 141B: 141B: pokeb equ $-v_tab 141B: C3D512 jp v_pokeb 141E: 141E: jump equ $-v_tab 141E: C30C13 jp v_jump 1421: 1421: if equ $-v_tab 1421: C39B12 jp v_if 1424: 1424: iff equ $-v_tab 1424: C3A212 jp v_iff 1427: 1427: ifff equ $-v_tab 1427: C3A912 jp v_ifff 142A: 142A: bra equ $-v_tab 142A: C31313 jp v_bra 142D: 142D: bra_if equ $-v_tab 142D: C31E13 jp v_bra_if 1430: 1430: bra_ifnot equ $-v_tab 1430: C32613 jp v_bra_ifnot 1433: 1433: call equ $-v_tab 1433: C33513 jp v_call 1436: 1436: opcode equ $-v_tab 1436: C32E13 jp v_opcode 1439: 1439: return equ $-v_tab 1439: C1 v_return pop bc 143A: FDE9 jp (iy) 143C: 143C: exit equ $-v_tab 143C: jp_calc equ $-v_tab 143C: C33F13 jp v_jp_calc 143F: 143F: call_calc equ $-v_tab 143F: C34413 jp v_call_calc 1442: 1442: penter equ $-v_tab 1442: C34B13 jp v_penter 1445: 1445: preturn equ $-v_tab 1445: C36313 jp v_preturn 1448: 1448: pexit equ $-v_tab 1448: C37113 jp v_pexit 144B: 144B: lvar equ $-v_tab 144B: C37B13 jp v_lvar 144E: 144E: lvar_poke equ $-v_tab 144E: C38A13 jp v_lvar_poke 1451: 1451: pp equ $-v_tab 1451: C39C13 jp v_pp 1454: 1454: mm equ $-v_tab 1454: C3A513 jp v_mm 1457: 1457: pp_peek equ $-v_tab 1457: C3B013 jp v_pp_peek 145A: 145A: mm_peek equ $-v_tab 145A: C3BA13 jp v_mm_peek 145D: 145D: peek_pp equ $-v_tab 145D: C3C413 jp v_peek_pp 1460: 1460: peek_mm equ $-v_tab 1460: C3CF13 jp v_peek_mm 1463: 1463: incr equ $-v_tab 1463: 13 inc de 1464: FDE9 jp (iy) 1466: 1466: decr equ $-v_tab 1466: 1B dec de 1467: FDE9 jp (iy) 1469: 1469: to_real equ $-v_tab 1469: C5 push bc 146A: C9 ret 146B: 146B: dup equ $-v_tab 146B: D5 push de 146C: FDE9 jp (iy) 146E: 146E: drop equ $-v_tab 146E: D1 pop de 146F: FDE9 jp (iy) 1471: 1471: nip equ $-v_tab 1471: E1 pop hl 1472: FDE9 jp (iy) 1474: 1474: over equ $-v_tab 1474: C3DB12 jp v_over 1477: 1477: pick equ $-v_tab 1477: C3E112 jp v_pick 147A: 147A: and equ $-v_tab 147A: C3DA13 jp v_and 147D: 147D: or equ $-v_tab 147D: C3E313 jp v_or 1480: 1480: xor equ $-v_tab 1480: C3EC13 jp v_xor 1483: 1483: shl equ $-v_tab 1483: C32816 jp v_shl 1486: 1486: shr equ $-v_tab 1486: C34116 jp v_shr 1489: 1489: umax equ $-v_tab 1489: C37712 jp v_umax 148C: 148C: umin equ $-v_tab 148C: C38112 jp v_umin 148F: 148F: max equ $-v_tab 148F: C38B12 jp v_max 1492: 1492: min equ $-v_tab 1492: C39312 jp v_min 1495: 1495: rnd equ $-v_tab 1495: C30616 jp v_rnd 1498: 1498: dealloc equ $-v_tab 1498: C3E010 jp v_mem_dealloc 149B: 149B: string equ $-v_tab 149B: C36716 jp v_string 149E: 149E: strlen equ $-v_tab 149E: C39A16 jp v_strlen 14A1: 14A1: catstr equ $-v_tab 14A1: C33D17 jp v_catstr 14A4: 14A4: leftstr equ $-v_tab 14A4: C38C17 jp v_leftstr 14A7: 14A7: rightstr equ $-v_tab 14A7: C36F17 jp v_rightstr 14AA: 14AA: midstr equ $-v_tab 14AA: C39C17 jp v_midstr 14AD: 14AD: substr equ $-v_tab 14AD: C3A217 jp v_substr 14B0: 14B0: upperstr equ $-v_tab 14B0: C30717 jp v_upperstr 14B3: 14B3: lowerstr equ $-v_tab 14B3: C32217 jp v_lowerstr 14B6: 14B6: charstr equ $-v_tab 14B6: C3DE16 jp v_charstr 14B9: 14B9: hex2str equ $-v_tab 14B9: C3CD16 jp v_hex2str 14BC: 14BC: hex4str equ $-v_tab 14BC: C3BF16 jp v_hex4str 14BF: 14BF: numstr equ $-v_tab 14BF: C3A616 jp v_numstr 14C2: 14C2: print equ $-v_tab 14C2: C37816 jp v_print 14C5: 14C5: printchar equ $-v_tab 14C5: C37116 jp v_printchar 14C8: 14C8: printdec equ $-v_tab 14C8: C38E16 jp v_printdec 14CB: 14CB: printhex equ $-v_tab 14CB: C39416 jp v_printhex 14CE: 14CE: bit equ $-v_tab 14CE: C37415 jp v_bit 14D1: 14D1: setbit equ $-v_tab 14D1: C3EA12 jp v_setbit 14D4: 14D4: clrbit equ $-v_tab 14D4: C3FB12 jp v_clrbit 14D7: 14D7: ;rol equ $-v_tab 14D7: ; jp v_rol 14D7: 14D7: ;ror equ $-v_tab 14D7: ; jp v_ror 14D7: 14D7: neg equ $-v_tab 14D7: 1B dec de 14D8: cpl equ $-v_tab 14D8: 1832 jr v_cpl 14DA: 14DA: swap equ $-v_tab 14DA: 1839 jr v_swap 14DC: 14DC: add equ $-v_tab 14DC: 183C jr v_add 14DE: 14DE: sub equ $-v_tab 14DE: 183F jr v_sub 14E0: 14E0: eq equ $-v_tab 14E0: 184F jr v_eq 14E2: 14E2: ne equ $-v_tab 14E2: 1842 jr v_ne 14E4: 14E4: gt equ $-v_tab 14E4: 1856 jr v_gt 14E6: 14E6: ge equ $-v_tab 14E6: 1866 jr v_ge 14E8: 14E8: lt equ $-v_tab 14E8: 1855 jr v_lt 14EA: 14EA: le equ $-v_tab 14EA: 185F jr v_le 14EC: 14EC: not equ $-v_tab 14EC: 186C jr v_not 14EE: 14EE: bool equ $-v_tab 14EE: 1870 jr v_bool 14F0: 14F0: getkey equ $-v_tab 14F0: 1874 jr v_getkey 14F2: 14F2: waitkey equ $-v_tab 14F2: 1877 jr v_waitkey 14F4: 14F4: abs equ $-v_tab 14F4: 1810 jr v_abs 14F6: 14F6: lvar_peek equ $-v_tab 14F6: 0A ld a,(bc) 14F7: ;inc bc 14F7: ;jr v_lvar_peek_ctd 14F7: 14F7: v_tab_end 14F7: 14F7: ; ------------------------------------- 14F7: ; Dispatcher table end 14F7: ; ------------------------------------- 14F7: 14F7: 14F7: ; ---------------------------------------- 14F7: ; peek value from local variable 14F7: ; lvar_peek -- 14F7: 14F7: v_lvar_peek_ctd 14F7: ;ld a,(bc) 14F7: 03 inc bc 14F8: 14F8: DD54 ld d,xh 14FA: DD5D ld e,xl 14FC: 87 add a ; x2 & cy=vz 14FD: 6F ld l,a ; l=offset 14FE: 9F sbc a ; sign extend 14FF: 67 ld h,a ; hl=offset 1500: 19 add hl,de ; hl=ix+offset 1501: 5E ld e,(hl) 1502: 23 inc hl 1503: 56 ld d,(hl) ; peek word 1504: FDE9 jp (iy) 1506: 1506: ; ---------------------------------------- 1506: ; Convert to absolute value 1506: ; note: fails for $8000 (obviously) 1506: ; abs -- 1506: 1506: CB7C v_abs bit 7,h 1508: CA7112 jp z,vip_dis 150B: ;jr v_neg 150B: 150B: ; ------------------------------------- 150B: ; negate arithmetic value 150B: ; note: fails for $8000 (obviously) 150B: ; neg -- 150B: 1B v_neg dec de 150C: ;jr v_cpl 150C: 150C: ; ------------------------------------- 150C: ; bitwise complement 150C: ; cpl -- 150C: 150C: 7A v_cpl ld a,d 150D: 2F cpl 150E: 57 ld d,a 150F: 7B ld a,e 1510: 2F cpl 1511: 5F ld e,a 1512: C32100 jp vip_iy ; note: v_neg wird von mul/div/rem zum Abschluss angesprungen, 1515: ; wenn das Ergebnis negativ wird: IY muss wieder restauriert werden. 1515: 1515: ; ------------------------------------- 1515: ; swap 1st and 2nd top stack data 1515: ; swap -- 1515: 1515: E1 v_swap pop hl 1516: D5 push de 1517: EB ex hl,de 1518: FDE9 jp (iy) 151A: 151A: ; ------------------------------------- 151A: ; add two values 151A: ; add -- 151A: 151A: E1 v_add pop hl 151B: 19 add hl,de 151C: EB ex hl,de 151D: FDE9 jp (iy) 151F: 151F: ; ------------------------------------- 151F: ; subtract 2nd from 1st value 151F: ; add -- 151F: 151F: E1 v_sub pop hl 1520: A7 and a 1521: ED52 vsub1 sbc hl,de 1523: EB ex hl,de 1524: FDE9 jp (iy) 1526: 1526: ; ------------------------------------- 1526: ; compare two values: true if not equal 1526: ; ne -- 1526: 1526: E1 v_ne pop hl 1527: A7 and a 1528: ED52 sbc hl,de 152A: 280B jr z,set0 152C: 110100 set1 ld de,1 152F: FDE9 jp (iy) 1531: 1531: ; ------------------------------------- 1531: ; compare two values: true if equal 1531: ; eq -- 1531: 1531: E1 v_eq pop hl 1532: A7 and a 1533: ED52 sbc hl,de 1535: 28F5 jr z,set1 1537: 110000 set0 ld de,0 153A: FDE9 jp (iy) 153C: 153C: ; ------------------------------------- 153C: ; signed compare value1 with value2: true if greater than 153C: ; gt -- 153C: 153C: E1 v_gt pop hl 153D: EB ex hl,de 153E: FE defb $fe ; cp a,N 153F: ;jr v_lt 153F: 153F: ; ------------------------------------- 153F: ; signed compare value1 with value2: true if less than 153F: ; lt -- 153F: 153F: E1 v_lt pop hl 1540: 7C ld a,h 1541: AA xor d 1542: FA5415 jp m,vge1 1545: ED52 vlt1 sbc hl,de 1547: 38E3 jr c,set1 1549: 18EC jr set0 154B: 154B: ; ------------------------------------- 154B: ; signed compare value1 with value2: true if less than or equal 154B: ; le -- 154B: 154B: E1 v_le pop hl 154C: EB ex hl,de 154D: FE defb $fe ; cp a,N 154E: 154E: ; ------------------------------------- 154E: ; signed compare value1 with value2: true if greater than or equal 154E: ; ge -- 154E: 154E: E1 v_ge pop hl 154F: 7C ld a,h 1550: AA xor d 1551: FA4515 jp m,vlt1 1554: ED52 vge1 sbc hl,de 1556: 38DF jr c,set0 1558: 18D2 jr set1 155A: 155A: ; ------------------------------------- 155A: ; negate boolean value 155A: ; may be used to force an arbitrary value to either 0 or 1 155A: ; not -- 155A: 155A: 7A v_not ld a,d 155B: B3 or e 155C: 28CE jr z,set1 155E: 18D7 jr set0 1560: 1560: ; ------------------------------------- 1560: ; make boolean value 1560: ; may be used to force an arbitrary value to either 0 or 1 1560: ; bool -- 1560: 1560: 7A v_bool ld a,d 1561: B3 or e 1562: 28D3 jr z,set0 1564: 18C6 jr set1 1566: 1566: ; ------------------------------------- 1566: ; test and get character code from the keyboard. 1566: ; returns 0 if no key available. 1566: ; getkey -- 1566: 1566: v_getkey 1566: CD751B call get_inkey 1569: 1803 jr vwk1 156B: 156B: ; ------------------------------------- 156B: ; wait for and get character code from the keyboard. 156B: ; waitkey -- 156B: 156B: v_waitkey 156B: CD5E1B call wait_inkey 156E: D5 vwk1 push de 156F: 5F ld e,a 1570: 1600 ld d,0 1572: FDE9 jp (iy) 1574: 1574: ; ------------------------------------- 1574: ; get bit [15=left..0=right] 1574: ; bit -- 1574: 1574: E1 v_bit pop hl ; hl=value; de=index 1575: 7B ld a,e 1576: E6F0 and $f0 1578: B2 or d 1579: 20BC jr nz,set0 ; return 0 if out of range 157B: 157B: 7B ld a,e 157C: CD0821 call calc_bmask 157F: CB5B bit 3,e 1581: 2801 jr z,vb1 1583: 6C ld l,h 1584: A5 vb1 and l 1585: 28B0 jr z,set0 1587: 18A3 jr set1 1589: 1589: ; ------------------------------------- 1589: ; UP: negate negative numbers in hl and de 1589: ; preset IY with v_neg if DE xor HL neg. 1589: 1589: ;up_vz_mult: 1589: ; ld a,h 1589: ; and d 1589: ; ret p 1589: 1589: up_vz_mult_quick 1589: 7C ld a,h 158A: AA xor d 158B: F29215 jp p,upvz1 158E: FD210B15 ld iy,v_neg ; Ergebnis wird negativ -> exit via v_neg 1592: 1592: CB7C upvz1 bit 7,h 1594: 2807 jr z,abs_de 1596: 1596: 2B dec hl 1597: 7C ld a,h 1598: 2F cpl 1599: 67 ld h,a 159A: 7D ld a,l 159B: 2F cpl 159C: 6F ld l,a 159D: 159D: CB7A abs_de bit 7,d 159F: C8 ret z 15A0: 15A0: 1B neg_de dec de 15A1: 7A ld a,d 15A2: 2F cpl 15A3: 57 ld d,a 15A4: 7B ld a,e 15A5: 2F cpl 15A6: 5F ld e,a 15A7: C9 ret 15A8: 15A8: 15A8: ; ------------------------------------- 15A8: ; Signed multiplication 15A8: ; Multiplikation DE = HL x DE 15A8: ; mult -- 15A8: 15A8: E1 v_mult pop hl 15A9: C5 push bc 15AA: 15AA: 7C ld a,h 15AB: B2 or d 15AC: FC8915 call m,up_vz_mult_quick 15AF: 15AF: 7C ld a,h ; Sortiere: DE ≤ HL 15B0: BA cp d 15B1: 2002 jr nz,$+4 15B3: 7D ld a,l 15B4: BB cp e 15B5: 3001 jr nc,$+3 15B7: EB ex hl,de ; HL = Multiplikand 15B8: 4A ld c,d ; CA = Multiplikator 15B9: 7B ld a,e 15BA: 110000 ld de,0 ; Ergebnissammler 15BD: 180A jr m1 15BF: 15BF: ; Multiplikand links schieben 15BF: 29 m2 add hl,hl 15C0: ; Multiplikator rechts schieben 15C0: CB39 m3 srl c 15C2: 1F rra 15C3: 30FA jr nc,m2 15C5: ; Bit=1 => Multiplikand addieren 15C5: EB ex hl,de 15C6: 19 add hl,de 15C7: EB ex hl,de 15C8: ; Multiplikand links schieben 15C8: 29 add hl,hl 15C9: ; Schleifenendtest 15C9: A7 m1 and a 15CA: 20F4 jr nz,m3 15CC: B9 cp c 15CD: 20F1 jr nz,m3 15CF: C1 pop bc 15D0: FDE9 jp (iy) 15D2: 15D2: ; ------------------------------------- 15D2: ; Signed division 15D2: ; div -- 15D2: 15D2: E1 v_div pop hl 15D3: C5 push bc 15D4: 15D4: 7C ld a,h 15D5: B2 or d 15D6: FC8915 call m,up_vz_mult_quick 15D9: 15D9: CDEF15 vd3 call div_hl_de 15DC: 5950 ld de,bc 15DE: C1 pop bc 15DF: FDE9 jp (iy) 15E1: 15E1: ; ------------------------------------- 15E1: ; Signed division remainder 15E1: ; The remainder has the same sign as the division result. 15E1: ; so that n1 / n2 = quot rem r <=> n1/n2-quot = remainder 15E1: ; rem -- 15E1: 15E1: E1 v_rem pop hl 15E2: C5 push bc 15E3: 15E3: 7C ld a,h 15E4: B2 or d 15E5: FC8915 call m,up_vz_mult_quick 15E8: 15E8: CDEF15 vr1 call div_hl_de 15EB: EB ex hl,de 15EC: C1 pop bc 15ED: FDE9 jp (iy) 15EF: 15EF: div_hl_de ; bc rem hl = hl / de 15EF: 3E10 ld a,16 15F1: 4D44 ld bc,hl 15F3: 210000 ld hl,0 ; hlbc := hl 15F6: 15F6: CB31 div2 sll c ; c := 2*c+1 15F8: CB10 rl b ; bc := 2*bc+1 15FA: ED6A adc hl,hl ; hlbc := 2*hlbc+1 15FC: 15FC: ED52 sbc hl,de ; subtract (test) 15FE: 3002 jr nc,div1 ; worked! 1600: 0D dec c ; else clear bit 0 of result 1601: 19 add hl,de ; and undo sub 1602: 3D div1 dec a 1603: 20F1 jr nz,div2 1605: C9 ret ; hl := rem; bc := quot 1606: 1606: 1606: ; ------------------------------------- 1606: ; Random Number 1606: ; Benutzt den Schieberegister-Algorithmus des AY-Soundchips 1606: ; 1606: ; ehl formen ein Shiftregister ((17 Bit)) 1606: ; ehl' = ehl<<1 + ( ehl.bit(16) ^ ehl.bit(14) ) 1606: ; 1606: ; rnd -- 1606: 1606: rnd_seed data 3 1606: 1606: 2A2D5B v_rnd ld hl,(rnd_seed) 1609: 3A2F5B ld a,(rnd_seed+2) 160C: 5F ld e,a ; seed = ehl ((lower 17 bit)) 160D: 160D: 1610 ld d,16 ; generate 16 new bits 160F: 160F: ; calculate 1 bit: 160F: 7C rnd1 ld a,h 1610: CB07 rlc a 1612: CB07 rlc a 1614: AB xor e 1615: CB0F rrc a ; cy = neues bit 1617: 1617: ED6A adc hl,hl ; shift ehl left, padding new bit 1619: CB13 rl e 161B: 161B: 15 dec d 161C: 20F1 jr nz,rnd1 ; next bit 161E: 161E: ; hl = seed = result 161E: 222D5B ld (rnd_seed),hl 1621: 7B ld a,e 1622: 322F5B ld (rnd_seed+2),a 1625: 1625: EB ex hl,de ; de = result 1626: FDE9 jp (iy) 1628: 1628: #if 0 1628: ; ---------------------------------------- 1628: ; rotate right 1628: ; ror -- 1628: 1628: v_ror pop hl ; ror -- 1628: ld a,e 1628: bit 3,a 1628: jr z,vror4 1628: 1628: ld d,h ; einmal 8 Rotationen en block 1628: ld h,l 1628: ld l,d 1628: 1628: vror4 and $07 1628: jr z,vror3 1628: ld e,a ; e=count 1628: sub a ; a=right cy collector 1628: 1628: vror2 srl h 1628: rr l 1628: rra 1628: 1628: dec e 1628: jr nz,vror2 1628: 1628: or a,h 1628: ld h,a 1628: 1628: vror3 ex hl,de 1628: jp (iy) 1628: 1628: ; ---------------------------------------- 1628: ; rotate left 1628: ; rol -- 1628: 1628: v_rol pop hl ; rol -- 1628: ld a,e 1628: bit 3,a 1628: jr z,vrol4 1628: 1628: ld d,h ; einmal 8 Rotationen en block 1628: ld h,l 1628: ld l,d 1628: 1628: vrol4 and $07 1628: jr z,vrol3 1628: ld e,a ; e=count 1628: sub a ; a=left cy collector 1628: 1628: vrol2 add hl,hl 1628: rla 1628: 1628: dec e 1628: jr nz,vrol2 1628: 1628: or a,l 1628: ld l,a 1628: 1628: vrol3 ex hl,de 1628: jp (iy) 1628: #endif 1628: 1628: ; ---------------------------------------- 1628: ; shift left 1628: ; shl -- 1628: 1628: E1 v_shl pop hl 1629: 7B ld a,e 162A: FE10 cp 16 162C: D23715 jp nc,set0 162F: CB5F bit 3,a 1631: 2803 jr z,vshl4 1633: 1633: 65 ld h,l ; einmal 8 Rotationen en block 1634: 2E00 ld l,0 1636: 1636: E607 vshl4 and $07 1638: 2804 jr z,vshl3 163A: 163A: 29 vshl2 add hl,hl 163B: 163B: 3D dec a 163C: 20FC jr nz,vshl2 163E: 163E: EB vshl3 ex hl,de 163F: FDE9 jp (iy) 1641: 1641: ; ---------------------------------------- 1641: ; shift right 1641: ; shr -- 1641: 1641: E1 v_shr pop hl 1642: 7B ld a,e 1643: FE10 cp 16 1645: D23715 jp nc,set0 1648: CB5F bit 3,a 164A: 2803 jr z,vshr4 164C: 164C: 6C ld l,h ; einmal 8 Rotationen en block 164D: 2600 ld h,0 164F: 164F: E607 vshr4 and $07 1651: 2807 jr z,vshr3 1653: 1653: CB3C vshr2 srl h 1655: CB1D rr l 1657: 1657: 3D dec a 1658: 20F9 jr nz,vshr2 165A: 165A: EB vshr3 ex hl,de 165B: FDE9 jp (iy) 165D: 165D: #if 0 165D: ; ------------------------------------- 165D: ; push value on heap 165D: ; hpush -- 165D: 165D: v_hpush ld hl,(hp) 165D: ld (hl),e 165D: inc hl 165D: ld (hl),d 165D: inc hl 165D: ld (hp),hl 165D: pop de 165D: jp (iy) 165D: #endif 165D: 165D: #if 0 165D: ; ------------------------------------- 165D: ; pop value from heap 165D: ; hpop -- 165D: 165D: v_hpop push de 165D: ld hl,(hp) 165D: dec hl 165D: ld d,(hl) 165D: dec hl 165D: ld e,(hl) 165D: ld (hp),hl 165D: jp (iy) 165D: #endif 165D: 165D: ; ------------------------------------- 165D: ; peek top value on heap 165D: ; hpeek -- 165D: 165D: D5 v_hpeek push de 165E: 2A215B ld hl,(mem_heap_ptr) 1661: 2B dec hl 1662: 56 ld d,(hl) 1663: 2B dec hl 1664: 5E ld e,(hl) 1665: FDE9 jp (iy) 1667: 1667: 1667: ; ------------------------------------- 1667: ; push immediate string 1667: ; string "text literal",0 -- 1667: 1667: v_string 1667: D5 push de 1668: 5950 ld de,bc 166A: 0A vs1 ld a,(bc) 166B: 03 inc bc 166C: A7 and a 166D: 20FB jr nz,vs1 166F: FDE9 jp (iy) 1671: 1671: ; ------------------------------------- 1671: ; print single character 1671: ; printchar -- 1671: 1671: v_printchar 1671: 7B ld a,e 1672: CDBC04 call print_char 1675: D1 pop de 1676: FDE9 jp (iy) 1678: 1678: ; ------------------------------------- 1678: ; print text 1678: ; print -- 1678: 1678: CD9F10 v_print call mem_is_handle_de ; nc:is handle 167B: EB ex hl,de 167C: 3005 jr nc,vp1 ; handle 167E: ; pointer: 167E: CDC204 call print_text_hl 1681: 1808 jr vp2 1683: ; handle: 1683: C5 vp1 push bc ; pc 1684: CD470F call mem_get_size_and_address; hl->data; bc=len 1687: CDD304 call print_text_hlbc 168A: C1 pop bc 168B: D1 vp2 pop de 168C: FDE9 jp (iy) 168E: 168E: ; ------------------------------------- 168E: ; print value as signed decimal number 168E: ; printdec -- 168E: 168E: v_printdec 168E: EB ex hl,de 168F: CD5804 call print_vz_dec 1692: 18F7 jr vp2 1694: 1694: ; ------------------------------------- 1694: ; print value as unsigned 4-letter hexadecimal number 1694: ; printhex -- 1694: 1694: v_printhex 1694: EB ex hl,de 1695: CD6104 call print_hex4 1698: 18F1 jr vp2 169A: 169A: ; ------------------------------------- 169A: ; calculate text length 169A: ; strlen -- 169A: 169A: v_strlen 169A: FDE5 push iy 169C: v_get_strlen_and_address: 169C: CD9F10 call mem_is_handle_de ; nc:is handle 169F: EB ex hl,de ; hl->handle/text 16A0: D2530F jp nc,mem_get_size_de_and_address ; handle 16A3: C33D20 jp calc_strlen ; pointer 16A6: 16A6: ; ------------------------------------- 16A6: ; convert value to signed decimal string 16A6: ; numstr -- 16A6: 16A6: v_numstr 16A6: C5 push bc 16A7: EB ex hl,de ; hl=value 16A8: 11275B ld de,v_scratch ; de->buffer 16AB: CD4920 call vzdecstr ; de++ 16AE: 21D9A4 ld hl,-v_scratch 16B1: 19 add hl,de ; hl=text size 16B2: 4D44 ld bc,hl ; bc=size 16B4: 16B4: CD0810 call mem_alloc ; bc=size; de->data; hl=handle 16B7: E5 push hl ; bc=size; de->data; sp:handle 16B8: 21275B ld hl,v_scratch 16BB: EDB0 ldir 16BD: 181B jr vhx2 16BF: 16BF: ; ------------------------------------- 16BF: ; convert value to unsigned 4-letter hexadecimal string 16BF: ; -- 16BF: 16BF: v_hex4str 16BF: C5 push bc 16C0: D5 push de 16C1: 010400 ld bc,4 16C4: CD0810 call mem_alloc ; bc=len; de->data; hl=handle 16C7: E3 ex hl,(sp) ; bc=len; de->data; hl=value; sp:handle 16C8: CDA520 call hexstr4 16CB: 180D jr vhx2 16CD: 16CD: ; ------------------------------------- 16CD: ; convert value to unsigned 2-letter hexadecimal string 16CD: ; -- 16CD: 16CD: v_hex2str 16CD: C5 push bc 16CE: D5 push de 16CF: 010200 ld bc,2 16D2: CD0810 call mem_alloc ; bc=len; de->data; hl=handle 16D5: E3 ex hl,(sp) ; bc=len; de->data; hl=value; sp:handle 16D6: 7D ld a,l 16D7: CDAC20 call hexstr2 16DA: D1 vhx2 pop de ; handle 16DB: C1 pop bc 16DC: FDE9 jp (iy) 16DE: 16DE: ; ------------------------------------- 16DE: ; convert character code to 1-letter text string 16DE: ; -- 16DE: 16DE: v_charstr 16DE: C5 push bc 16DF: D5 push de 16E0: 010100 ld bc,1 16E3: CD0810 call mem_alloc 16E6: EB ex hl,de ; de-> handle; hl->data 16E7: C1 pop bc ; value 16E8: 71 ld (hl),c 16E9: C1 pop bc ; pc 16EA: FDE9 jp (iy) 16EC: 16EC: ; ---------------------------------------------- 16EC: ; UP: make mem handle from 0-terminated string 16EC: ; 16EC: ; in: de = address or handle 16EC: ; out: hl = data address 16EC: ; de = handle 16EC: ; bc = size 16EC: 16EC: make_handle: 16EC: CD9F10 call mem_is_handle_de ; nc:handle 16EF: 6B62 ld hl,de ; hl = de = handle 16F1: D2470F jp nc,mem_get_size_and_address ; bc=size; de=handle; hl->data 16F4: ; pointer 16F4: CD3D20 mh1 call calc_strlen ; hl->text; de=size 16F7: 4B42 ld bc,de ; bc=size 16F9: 16F9: C5 push bc ; sp: len 16FA: E5 push hl ; sp: ->source text 16FB: CD0810 call mem_alloc ; bc=len; hl=handle; de->buffer; z/nz 16FE: E3 ex hl,(sp) ; sp: len,handle; hl->source 16FF: D5 push de ; sp: len,handle,->data; 1700: C46210 call nz,ldir 1703: E1 pop hl ; hl->data 1704: D1 pop de ; de=handle 1705: C1 pop bc ; bc=len 1706: C9 ret 1707: 1707: ; ------------------------------------- 1707: v_upperstr ; -- 1707: C5 push bc 1708: CDEC16 call make_handle ; text -- hl->text; de=handle; bc=len 170B: 0C inc c 170C: 04 inc b 170D: 180B jr us1 170F: 7E us2 ld a,(hl) 1710: D661 sub 'a' 1712: FE7B cp 'z'+1 1714: 3003 jr nc,us3 1716: C641 add 'A' 1718: 77 ld (hl),a 1719: 23 us3 inc hl 171A: 0D us1 dec c 171B: 20F2 jr nz,us2 171D: 10F0 djnz us2 171F: C1 pop bc 1720: FDE9 jp (iy) 1722: 1722: ; ------------------------------------- 1722: v_lowerstr ; -- 1722: C5 push bc 1723: CDEC16 call make_handle ; text -- hl->text; de=handle; bc=len 1726: 0C inc c 1727: 04 inc b 1728: 180B jr ls1 172A: 7E ls2 ld a,(hl) 172B: D641 sub 'A' 172D: FE5B cp 'Z'+1 172F: 3003 jr nc,ls3 1731: C661 add 'a' 1733: 77 ld (hl),a 1734: 23 ls3 inc hl 1735: 0D ls1 dec c 1736: 20F2 jr nz,ls2 1738: 10F0 djnz ls2 173A: C1 pop bc 173B: FDE9 jp (iy) 173D: 173D: ; ------------------------------------- 173D: v_catstr ; -- 173D: 173D: E1 pop hl ; de=text2; hl=text1 173E: C5 push bc 173F: 173F: D5 push de ; sp:text2 1740: E5 push hl ; sp:text2,text1 1741: 1741: E5 push hl 1742: CD9C16 call v_get_strlen_and_address ; de=strlen2 1745: E1 pop hl 1746: D5 push de ; sp:text2,text1,strlen2 1747: EB ex hl,de 1748: CD9C16 call v_get_strlen_and_address ; de=strlen1 174B: E1 pop hl ; sp:text2,text1; hl=strlen2; de=strlen1 174C: 19 add hl,de ; hl=len1+2 174D: 174D: 4D44 ld bc,hl ; bc=len3 174F: CD0810 call mem_alloc ; bc=len3; de->data3; hl=handle3; sp:text2,text1 1752: 1752: E3 ex hl,(sp) ; bc=len3; de->data3; hl=text1; sp:text2,handle3 1753: 1753: D5 push de ; data3 1754: EB ex hl,de ; de=text1 1755: CD9C16 call v_get_strlen_and_address ; de=len1; hl=addr1 1758: 4B42 ld bc,de ; bc=len1 175A: D1 pop de ; de=data3 175B: CD5F10 call ldir_if_nz ; de++ 175E: 175E: E1 pop hl ; de=dest; hl=handle3; sp:text2 175F: E3 ex hl,(sp) ; de=dest; sp=handle3; hl:text2 1760: D5 push de ; dest 1761: EB ex hl,de ; de=text2 1762: CD9C16 call v_get_strlen_and_address ; de=len2; hl=addr2 1765: 4B42 ld bc,de ; bc=len2 1767: D1 pop de ; de=dest 1768: CD5F10 call ldir_if_nz 176B: 176B: D1 pop de ; handle 176C: C1 pop bc ; pc 176D: FDE9 jp (iy) 176F: 176F: ; ------------------------------------- 176F: v_rightstr ; -- 176F: E1 pop hl 1770: C5 push bc 1771: CD9710 call mem_is_handle ; nc:handle 1774: 3807 jr c,vrs1 1776: ; handle 1776: CD9E11 call mem_rshrink 1779: EB ex hl,de 177A: C1 pop bc 177B: FDE9 jp (iy) 177D: ; pointer 177D: 4B42 vrs1 ld bc,de ; bc=new size 177F: CD3D20 call calc_strlen ; hl->text; de=old size 1782: EB ex hl,de ; bc=new size; de->text; hl=old size 1783: A7 and a 1784: ED42 sbc hl,bc ; hl=old-new size 1786: 3801 jr c,vrs2 ; old no action 1788: 19 add hl,de ; hl=old text addr+old size-new size = new text address 1789: EB vrs2 ex hl,de ; de=new text address 178A: C1 pop bc 178B: C9 ret 178C: 178C: ; ------------------------------------- 178C: v_leftstr ; -- 178C: E1 pop hl ; hl:text 178D: C5 push bc 178E: 178E: D5 push de ; sp:new size 178F: EB ex hl,de ; de:text 1790: CDEC16 call make_handle ; text -- hl->text; de=handle; bc=len 1793: EB ex hl,de ; hl=handle 1794: D1 pop de ; de=new size 1795: CD9911 call mem_shrink 1798: EB ex hl,de 1799: 1799: C1 pop bc 179A: FDE9 jp (iy) 179C: 179C: ; ------------------------------------- 179C: v_midstr ; -- 179C: E1 pop hl ; de=count;hl=start 179D: EB ex hl,de ; hl=count;de=start 179E: 19 add hl,de ; hl=end;de=start 179F: EB ex hl,de ; hl=start;de=end 17A0: 1801 jr vsr1 17A2: 17A2: ; ------------------------------------- 17A2: v_substr ; -- 17A2: 17A2: E1 pop hl ; hl=start; de=end 17A3: F1 vsr1 pop af ; af=text 17A4: 17A4: C5 push bc 17A5: D5 push de 17A6: E5 push hl ; sp:start,end 17A7: 17A7: F5 push af 17A8: D1 pop de ; de=text 17A9: CDEC16 call make_handle ; text -- hl->text; de=handle; bc=len 17AC: EB ex hl,de ; hl=handle 17AD: D1 pop de ; de=end 17AE: C1 pop bc ; bc=start 17AF: CDCB11 call mem_subrange 17B2: EB ex hl,de 17B3: 17B3: C1 pop bc 17B4: FDE9 jp (iy) 17B6: 17B6: ; ------------------------------------- 17B6: ; push data on heap 17B6: v_hpushdata: ;
hpushdata -- 17B6: E1 pop hl ; address 17B7: C5 push bc ; pc 17B8: 4B42 ld bc,de ; size 17BA: CD3510 call mem_heap_push_data ; hl:handle; de:ziel; bc:size; z/nz 17BD: C1 pop bc ; pc 17BE: FDE9 jp (iy) 17C0: 17C0: ; ------------------------------------------------------------ 17C0: ; Restore data from heap 17C0: v_hpopdata: ; hpopdata -- 17C0: CD5210 call mem_heap_pop_data 17C3: D1 pop de 17C4: FDE9 jp (iy) 17C6: 17C6: 17C6: 17C6: 17C6: ; -------------------------------------- 17C6: ; Edit text 17C6: 17C6: 17C6: ; 17C6: ; in: B,C = top left corner of box 17C6: ; D,E = rows/cols; D=1 17C6: ; HL -> text 17C6: ; out: HL -> text 17C6: ; mod: 17C6: 17C6: edit_text: ; edittext -- 17C6: 17C6: ed_text equ 5 17C6: ed_top equ 4 17C6: ed_left equ 3 17C6: ed_width equ 2 17C6: ed_key equ -1 17C6: ed_pos equ -2 17C6: 17C6: 4202 db penter, 2 17C8: F6059E4E 17CC: FE db lvar_peek, ed_text, strlen, lvar_poke, ed_pos 17CD: 17CD: ; print current text with cursor 17CD: F604 edtxt0 db lvar_peek, ed_top 17CF: F603 db lvar_peek, ed_left 17D1: 36FD04 db opcode, v_locate%256, v_locate/256 17D4: F602 db lvar_peek, ed_width 17D6: 36C607 db opcode, v_clear_cols%256, v_clear_cols/256 17D9: F605F6FE 17DD: A4C2 db lvar_peek, ed_text, lvar_peek, ed_pos, leftstr, print 17DF: 0094C5 db byte, charcode_icursor, printchar 17E2: F605F6FE 17E6: 0063AAC2 db lvar_peek, ed_text, lvar_peek, ed_pos, byte, 99, midstr, print 17EA: 17EA: ; wait for key 17EA: F2 db waitkey 17EB: 6B4EFF db dup, lvar_poke, ed_key 17EE: 0020E8 db byte, ' ', lt 17F1: 242A18 db iff, bra, edtxt1-$ 17F4: 17F4: ; printable character 17F4: F605F6FE 17F8: A4 db lvar_peek, ed_text, lvar_peek, ed_pos, leftstr 17F9: F6FFB6A1 db lvar_peek, ed_key, charstr, catstr 17FD: F605F6FE 1801: 0063AAA1 db lvar_peek, ed_text, lvar_peek, ed_pos, byte, 99, midstr, catstr 1805: 4E05 db lvar_poke, ed_text 1807: 2AC6 db bra, edtxt0-$ 1809: 1809: ; control code 1809: F6FF edtxt1 db lvar_peek, ed_key 180B: 6B05E0 db dup, keycode_left, eq ; crsr left? 180E: 242A11 db iff, bra, edtxt2-$ 1811: 6B08E0 db dup, keycode_right, eq ; crsr right? 1814: 242A16 db iff, bra, edtxt3-$ 1817: 6B0DE0 db dup, keycode_return, eq ; enter? 181A: 242A1C db iff, bra, edtxt4-$ 181D: 2AB0 db bra, edtxt0-$ ; else ignore 181F: 181F: ; cursor left 181F: 6E edtxt2 db drop 1820: F6FE6600 1824: 008F4EFE db lvar_peek, ed_pos, decr, byte, 0, max, lvar_poke, ed_pos 1828: 2AA5 db bra, edtxt0-$ 182A: 182A: ; cursor right 182A: 6E edtxt3 db drop 182B: F6FE63F6 182F: 059E924E 1833: FE db lvar_peek, ed_pos, incr, lvar_peek, ed_text, strlen, min, lvar_poke, ed_pos 1834: 2A99 db bra, edtxt0-$ 1836: 1836: ; enter 1836: 6E edtxt4 db drop 1837: F604F603 183B: 36FD04 db lvar_peek, ed_top, lvar_peek, ed_left, opcode, v_locate%256, v_locate/256 183E: F60236C6 1842: 07 db lvar_peek, ed_width, opcode, v_clear_cols%256, v_clear_cols/256 1843: F605C2 db lvar_peek, ed_text, print 1846: 1846: F6054504 db lvar_peek, ed_text, preturn, 4 184A: 184A: 184A: 184A: 184A: #include "vip.ass" 184A: vip_end equ $ 184A: 184A: 184A: 184A: 184A: 184A: ; -------------------------------------------------- 184A: ; RAM testen und löschen 184A: ; 184A: ; Testet und löscht das gesamte RAM mit $00. 184A: ; 184A: ; Wenn die unteren 16k RAM nicht fehlerfrei sind, kehrt ram_test nicht zurück 184A: ; sondern sendet einen Fehlercode mittels Borderflashing. (TODO) 184A: ; Aktuell signalisiert Border rot defektes RAM oder defekte Datenleitungen 184A: ; und Border magenta defekte Adressleitungen. 184A: ; 184A: ; ram_test sollte defekte Bits, defekte Bausteine, den Totalausfall des RAMs, 184A: ; defekte Datenleitungen und defekte Adressleitungen erkennen. 184A: ; 184A: ; Interrupts müssen selbstverständlich gesperrt sein. 184A: ; ram_test benutzt und setzt den Stackpointer sp nicht. 184A: ; 184A: ; in: iy = return address 184A: ; interrupts disabled 184A: ; out: hl = ramtop = pointer behind usable ram; e.g. $8000 (16k) or $0000 (48k) 184A: ; mod: af,bc,de,hl 184A: 184A: 184A: ram_test: 184A: 184A: ; Gesamten Speicher byteweise prüfen 184A: ; 8x single bit 1 and 8x single bit 0 184A: 184A: 3E80 ld a,$80 ; a = pattern = $7F = %10000000 184C: 210040 ld hl,$4000 184F: 184F: 2F cs1 cpl 1850: 77 ld (hl),a 1851: BE cp (hl) 1852: 200B jr nz,cs2 1854: 1854: 2F cpl 1855: 77 ld (hl),a 1856: BE cp (hl) 1857: 2006 jr nz,cs2 1859: 1859: 0F rrca 185A: 30F3 jr nc,cs1 ; same byte, next bit 185C: 23 inc hl 185D: 18F0 jr cs1 ; next byte; Abbruch durch defekte Zelle oder ROM 185F: 185F: 2B cs2 dec hl ; hl = RAMTOP -1 1860: 7C ld a,h 1861: FE7F cp $7F 1863: 381C jr c,ram_broken_1 ; weniger als 16k 1865: 1865: ; hl = RAMTOP -1 ($7FFF oder $FFFF) 1865: ; RAM = $01 1865: 1865: ; Auf Faltung (defekte Adressleitungen) prüfen und RAM löschen: 1865: 1865: 5D54 ld de,hl ; de = RAMTOP -1 1867: 21FF3F ld hl,$3FFF ; hl = pointer = $4000 -1 186A: 186A: 23 cs3 inc hl 186B: 35 dec (hl) ; $01 -> $00 186C: 28FC jr z,cs3 ; Abbruch bei gespiegelter Zelle oder ROM 186E: AF xor a ; a = 0 & nc 186F: 77 ld (hl),a ; falls Abbruch wg. inc(hl)!=0 dann die gespiegelte Zelle nullen 1870: 2B dec hl ; hl = RAMTOP -1 1871: 1871: ; hl = new RAMTOP -1, de = old RAMTOP -1 1871: ; RAM = $00 1871: 1871: ED52 sbc hl,de 1873: EB ex hl,de 1874: 3801 jr c,cs5 1876: 19 add hl,de ; hl = RAMTOP -1 = min(old RAMTOP -1, new RAMTOP -1) 1877: 1877: 7C cs5 ld a,h 1878: FE7F cp $7F 187A: 380B jr c,ram_broken_2 ; weniger als 16k 187C: 187C: ; Set RAMTOP and Stack 187C: 23 inc hl ; hl = RAMTOP 187D: CB85 res 0,l ; force even 187F: 187F: FDE9 jp (iy) ; return 1881: 1881: 1881: 1881: 1881: 1881: ; in: hl = RAMTOP-1 1881: ; wenn hl+1==$4000 1881: ; dann ist gar kein RAM nutzbar: 1881: ; RAM komplett ausgefallen (Hilfsspannungen fehlen) 1881: ; Einzelne RAM-Chips sind komplett ausgefallen 1881: ; Problem mit Datenleitungen: Bit always 0, always 1, shortened 1881: ; sonst sind nur einzelne Zellen der low 16k defekt 1881: 1881: ram_broken_1: 1881: 3E02 ld a,red ; border 1883: D3FE out ($FE),a 1885: 18FE jr $ 1887: 1887: ; in: hl = RAMTOP-1 1887: ; wenn hl+1<$8000 1887: ; dann gibt es ein Problem bei den Adressleitungen auf dem ULA Bus oder Z80 Bus 1887: ; sonst Adressleitungsproblem auf Z80 Bus 1887: ram_broken_2: 1887: 3E03 ld a,magenta ; border 1889: D3FE out ($FE),a 188B: 18FE jr $ 188D: 188D: 188D: #include "ram test.ass" 188D: 188D: 188D: ; --------------------------------------------- 188D: ; E R R O R H A N D L I N G 188D: ; --------------------------------------------- 188D: 188D: 188D: ; -------------------------------------------------------- 188D: ; Initialisierung 188D: ; 188D: ; in: -- 188D: ; out: -- 188D: ; mod: -- 188D: 188D: init_errors: 188D: 212819 ld hl,oomem_handler 1890: C3C018 jp set_error_handler 1893: 1893: 1893: 1893: errno data 1 1893: error_msg_handle data 2 ; handle, if errno = error_message 1893: error_handler data 2 1893: 1893: 1893: noerror equ 0 1893: error_message equ 1 ; message handle in error_msg 1893: error_oomem equ 2 1893: error_notester equ 3 1893: 1893: ; matching messages: 1893: 1893: 00 error_messages defb 0 ; 0 = no error 1894: 00 defb 0 ; 1 = custom error message 1895: 4F757420 1899: 6F66206D 189D: 656D6F72 18A1: 792E00 defm "Out of memory.",0 ; 2 18A4: 54657374 18A8: 6572206E 18AC: 6F742066 18B0: 6F756E64 18B4: 2E00 defm "Tester not found.",0 ; 3 18B6: 00 defb 0 ; stopper 18B7: 18B7: 18B7: ; -------------------------------------------------------- 18B7: ; abort with out-of-memory 18B7: ; 18B7: abort_oomem: 18B7: 3E02 ld a,error_oomem 18B9: ;jr abort 18B9: 18B9: 18B9: 18B9: ; -------------------------------------------------------- 18B9: ; Set errno and jump to memory error handler. 18B9: ; If no error handler was defined, then it restarts the computer. 18B9: ; does not return 18B9: ; 18B9: ; in: a = error number 18B9: ; out: -- 18B9: ; mod: does not return 18B9: 18B9: abort: 18B9: 32305B ld (errno),a 18BC: 2A335B ld hl,(error_handler) 18BF: E9 jp (hl) 18C0: 18C0: 18C0: 18C0: ; --------------------------------------- 18C0: ; Set error handler 18C0: ; 18C0: ; in: hl = new handler 18C0: ; out: -- 18C0: ; mod: -- 18C0: 18C0: set_error_handler: 18C0: 22335B ld (error_handler),hl 18C3: C9 ret 18C4: 18C4: 18C4: 18C4: ; --------------------------------------- 18C4: ; Get error handler 18C4: ; 18C4: ; in: -- 18C4: ; out: hl = current handler 18C4: ; mod: -- 18C4: 18C4: get_error_handler: 18C4: 2A335B ld hl,(error_handler) 18C7: C9 ret 18C8: 18C8: 18C8: 18C8: 18C8: 18C8: ; ------------------------------- 18C8: ; set custom error message 18C8: ; 18C8: ; in: hl->0-terminated message 18C8: ; out: hl->Kopie des Meldungstextes 18C8: ; mod: af, hl 18C8: 18C8: set_error_message: 18C8: D5 push de 18C9: C5 push bc 18CA: 18CA: 3E01 ld a,error_message 18CC: 32305B ld (errno),a 18CF: 5D54 ld de,hl 18D1: 97 sub a 18D2: 18D2: BE sem1 cp (hl) 18D3: 23 inc hl 18D4: 20FC jr nz,sem1 18D6: 18D6: ED52 sbc hl,de 18D8: EB ex hl,de ; hl -> message (again) 18D9: 4B42 ld bc,de ; bc = size 18DB: 18DB: CD3B10 call mem_save_data 18DE: 22315B ld (error_msg_handle),hl 18E1: EB ex hl,de ; hl -> data 18E2: 18E2: C1 pop bc 18E3: D1 pop de 18E4: C9 ret 18E5: 18E5: 18E5: 18E5: ; -------------------------------------------------------- 18E5: ; Fehlermeldung ausgeben, falls vorhanden 18E5: ; 18E5: ; in: -- 18E5: ; out: -- 18E5: ; mod: af 18E5: 18E5: print_error_message: 18E5: 18E5: 3A305B ld a,(errno) 18E8: A7 and a 18E9: C8 ret z ; no error 18EA: 18EA: D7 rst save_registers 18EB: 18EB: FE01 cp error_message ; custom message ? 18ED: 200E jr nz,pem1 ; no 18EF: 18EF: ; error message on heap: 18EF: 2A315B ld hl,(error_msg_handle) 18F2: E5 push hl 18F3: CD5C0F call mem_get_address 18F6: CD0819 call up_show_error 18F9: E1 pop hl 18FA: C34D10 jp mem_dealloc 18FD: 18FD: 219318 pem1 ld hl,error_messages 1900: 47 ld b,a ; b = counter = error no. 1901: AF xor a ; a = 0 1902: 1902: BE pem2 cp (hl) 1903: 23 inc hl 1904: 20FC jr nz,pem2 ; not 0 1906: 10FA djnz pem2 ; 0 found, count down msg.no. 1908: 1908: ; hl -> message 1908: up_show_error: 1908: 3E57 ld a,red_paper+bright+white 190A: 011408 ld bc,8*256+20 ; bc = rows,cols 190D: CDCD19 call open_alert ; de = top,left 1910: CD3A1A call alert_set_main_text 1913: 3E47 ld a,black_paper+white+bright 1915: 320F5B ld (print_attr),a 1918: 219C19 ld hl,msg_presskey 191B: CD941A call alert_add_button 191E: 191E: AF xor a 191F: 32305B ld (errno),a ; clear errno 1922: 1922: CD5E1B call wait_inkey 1925: C3CC1A jp close_alert 1928: 1928: 1928: 1928: 1928: 1928: 1928: 1928: oomem_handler: 1928: ED7B005B ld sp,(RAMTOP) ; reset stack 192C: CD9B0E call mem_compact 192F: 192F: 21305B ld hl,errno 1932: 3E02 ld a,error_oomem 1934: BE cp (hl) 1935: 77 ld (hl),a 1936: C2BE00 jp nz,main_menu ; not re-issued => proceed. main_menu will display error. 1939: 1939: ; oomem in oomem processing 1939: CDCC03 oo_oo call print_reset 193C: CF rst print_msg 193D: 010617 defm ctl_home,ctl_setattr,red_paper+white 1940: 1A536576 1944: 65726520 1948: 6D656D6F 194C: 72792073 1950: 686F7274 1954: 6167652E 1958: 0D defm ctl_clr2eol,"Severe memory shortage.", $0d 1959: 1A547279 195D: 20746F20 1961: 73617665 1965: 20287768 1969: 61746576 196D: 65722920 1971: 616E6420 1975: 72657365 1979: 742E0D defm ctl_clr2eol,"Try to save (whatever) and reset.", $0d 197C: 1A507265 1980: 7373206B 1984: 65792066 1988: 6F72206D 198C: 61696E20 1990: 6D656E75 1994: 2E00 defm ctl_clr2eol,"Press key for main menu.", 0 1996: CD5E1B call wait_inkey 1999: C3BE00 jp main_menu 199C: 199C: 199C: 199C: 199C: 199C: #include "errors.ass" 199C: 199C: 199C: 199C: ; -------------------------------------------------- 199C: ; ERRORS, ALERTS & REQUESTER 199C: ; -------------------------------------------------- 199C: 199C: ; all measurement is in 8x8 character cells 199C: 199C: 199C: 20707265 19A0: 73732061 19A4: 6E79206B 19A8: 65792000 msg_presskey: defm " press any key ",0 19AC: 206F6B20 19B0: 00 msg_ok: defm " ok ",0 19B1: 20796573 19B5: 2000 msg_yes: defm " yes ",0 19B7: 206E6F20 19BB: 00 msg_no: defm " no ",0 19BC: 2063616E 19C0: 63656C20 19C4: 00 msg_cancel: defm " cancel ",0 19C5: 20454E54 19C9: 45522000 msg_enter: defm " ENTER ",0 19CD: 19CD: 19CD: ; open_alert A BC -- BC DE 19CD: ; alert_set_main_text BC DE HL -- BC DE 19CD: ; alert_add_button BC DE HL -- BC DE 19CD: ; close_alert -- 19CD: 19CD: 19CD: 19CD: 19CD: 19CD: ; -------------------------------------------------- 19CD: ; Open Alert Box 19CD: ; 19CD: ; Calculate x/y position for alert 19CD: ; Saves attributes on heap -> IX 19CD: ; Saves pixels of main text area on heap -> IX 19CD: ; Draws new box with attributes only 19CD: ; sets print attribute for subsequent alert text printing 19CD: ; 19CD: ; note: flashing geht da nicht... 19CD: ; 19CD: ; in: B = rows (char cells) [1..23] 19CD: ; C = columns (char cells) [2..30] 19CD: ; A = attribute no flashing! 19CD: ; out: D/E = top row/left column of usable area 19CD: ; B/C = rows/cols of usable area for main text + buttons 19CD: ; mod: AF, BC, DE 19CD: 19CD: open_alert: 19CD: E5 push hl ; preserve 19CE: C5 push bc ; alertbox.rows/cols 19CF: 19CF: 320F5B ld (print_attr),a 19D2: 19D2: ; calc clear color 19D2: E6F8 and $F8 19D4: 5F ld e,a ; e = attribut ohne pen bits 19D5: 1F rra 19D6: 1F rra 19D7: 1F rra 19D8: E607 and 7 ; a = paper bits moved to pen position 19DA: B3 or e ; a = attr mit pen == paper 19DB: F5 push af ; attr 19DC: 19DC: C5 push bc ; sp: width, height 19DD: 19DD: ; calc location for top/left corner: 19DD: 3E18 ld a,24 ; screen height 19DF: 90 sub b ; remaining rows 19E0: 47 ld b,a 19E1: 87 add a 19E2: 87 add a 19E3: 80 add b ; rem.rows*5 19E4: 0F rrca 19E5: 0F rrca 19E6: 0F rrca 19E7: 0F rrca 19E8: E60F and $f ; rem.rows*5/16 ~ 1/3 19EA: 47 ld b,a ; b = top row 19EB: 19EB: 3E20 ld a,32 ; screen width 19ED: 91 sub c 19EE: 1F rra 19EF: 4F ld c,a ; c = left column 19F0: 19F0: ; save attr bytes 19F0: CD390E call calc_attr_hl_for_row_b_col_c ; -> hl 19F3: 5950 ld de,bc ; de = row/col of top/left corner 19F5: C1 pop bc ; bc = height,width 19F6: 04 inc b ; +1 for shadow 19F7: 0C inc c ; +1 for shadow 19F8: E5 push hl 19F9: CD030D call scr_save_attributes ; save attributes on heap 19FC: E1 pop hl 19FD: 05 dec b ; undo +1 19FE: 0D dec c ; undo +1 19FF: 19FF: ; clear attr box: 19FF: F1 pop af ; a = attr 1A00: CD640C call clear_attributes 1A03: 1A03: ; draw drop shadow: 1A03: D5 push de ; sp: row/col of top/left corner 1A04: 1A04: 59 ld e,c ; width 1A05: 1600 ld d,0 1A07: 19 add hl,de ; hl -> right beyond top/right corner 1A08: 1E20 ld e,32 ; de = 32 = offset/row 1A0A: ;ld b,b ; b = rows 1A0A: 19 oa1 add hl,de ; step down 1A0B: CBB6 res 6,(hl) ; clear bright bit 1A0D: 10FB djnz oa1 1A0F: ; now hl -> right/left beyond bottom/right corner of box 1A0F: 41 ld b,c ; b = cols 1A10: CBB6 oa2 res 6,(hl) ; clear bright bit 1A12: 2B dec hl 1A13: 10FB djnz oa2 1A15: 1A15: D1 pop de ; de = row/col of top/left corner 1A16: C1 pop bc ; bc = rows/cols 1A17: E1 pop hl ; hl 1A18: 1A18: ; adjust box.top/left and box.rows/cols 1A18: ; to cover usable for main text only. 1A18: 14 inc d ; top += 2 1A19: 14 inc d 1A1A: 1A1A: 1C inc e ; left += 2 1A1B: 1C inc e 1A1C: 1A1C: 78 ld a,b 1A1D: D605 sub 5 1A1F: 47 ld b,a ; rows -= 5 = 2 top, 1 below, 1 buttons, 1 below 1A20: 1A20: 79 ld a,c ; cols -= 4 = 2 left, r right 1A21: D604 sub 4 1A23: 4F ld c,a 1A24: 1A24: CD2A1A call alert_save_pixels ; main text area pixels 1A27: 1A27: 04 inc b ; add 2 rows to include the buttons row 1A28: 04 inc b 1A29: C9 ret 1A2A: 1A2A: 1A2A: 1A2A: ; -------------------------------------------------- 1A2A: ; Save pixels of text area 1A2A: ; 1A2A: ; in: de = top/left corner 1A2A: ; bc = rows/cols 1A2A: ; out: -- 1A2A: ; mod: af, iy 1A2A: 1A2A: alert_save_pixels: 1A2A: D7 rst save_registers 1A2B: C5 push bc ; size 1A2C: 4B42 ld bc,de ; loc 1A2E: CD480E call calc_pixel_hl_for_row_b_col_c 1A31: C1 pop bc 1A32: E5 push hl 1A33: CDD20C call scr_save_pixels ; save pixels on heap 1A36: E1 pop hl 1A37: C3460C jp clear_pixels_quick 1A3A: 1A3A: 1A3A: 1A3A: ; -------------------------------------------------- 1A3A: ; Add text to alert box 1A3A: ; 1A3A: ; in: hl -> text, delimited with 0-byte 1A3A: ; de = top/left corner of usable area for main text 1A3A: ; bc = rows/cols of usable area for main text + buttons 1A3A: ; out: -- 1A3A: ; mod: af 1A3A: 1A3A: alert_set_main_text: 1A3A: D7 rst save_registers 1A3B: 1A3B: 05 dec b ; subtract the buttons area 1A3C: 05 dec b 1A3D: C8 ret z ; bu hu 1A3E: 1A3E: 7B ld a,e ; cell col -> pixel col 1A3F: 87 add a 1A40: 87 add a 1A41: 87 add a 1A42: 5F ld e,a 1A43: 1A43: 79 ld a,c ; cell col -> pixel col 1A44: 87 add a 1A45: 87 add a 1A46: 87 add a 1A47: 4F ld c,a 1A48: 1A48: C5 absmt1 push bc 1A49: D5 push de 1A4A: CD7C1A call up_print_some_text 1A4D: D1 pop de 1A4E: C1 pop bc 1A4F: 1A4F: 7E absmt5 ld a,(hl) 1A50: A7 and a 1A51: C8 ret z ; end of text reached => exit 1A52: FE20 cp ' ' 1A54: 3809 jr c,absmt4 ; control code 1A56: 23 inc hl 1A57: 28F6 jr z,absmt5 ; skip space(s) 1A59: 2B dec hl 1A5A: 1A5A: ; text wraps => resume with next row 1A5A: 14 absmt2 inc d ; top row++ 1A5B: 05 dec b ; rows-- 1A5C: 20EA jr nz,absmt1 1A5E: C9 ret ; out of space 1A5F: 1A5F: ; break at control code: 1A5F: CDBC04 absmt4 call print_char ; print the control code 1A62: 23 inc hl 1A63: CD0D04 call print_calc_ctl_args 1A66: FE01 cp 1 1A68: 38E5 jr c,absmt5 ; 0 args 1A6A: 2807 jr z,absmt3 ; 1 arg 1A6C: 1A6C: 7E ld a,(hl) ; print 2 arg 1A6D: A7 and a 1A6E: C8 ret z 1A6F: CDBC04 call print_char 1A72: 23 inc hl 1A73: 1A73: 7E absmt3 ld a,(hl) ; print 1 arg 1A74: A7 and a 1A75: C8 ret z 1A76: CDBC04 call print_char 1A79: 23 inc hl 1A7A: 18D3 jr absmt5 1A7C: 1A7C: 1A7C: 1A7C: ; --------------------------------------------------------- 1A7C: ; UP: print some text (hl)++ 1A7C: ; in: hl -> text, delimited with 0-byte 1A7C: ; de = top/left corner (e=textpixels) 1A7C: ; bc = rows/cols (c=textpixels) 1A7C: ; out: hl -> 0 or hl-> remaining text to print in next line 1A7C: ; mod: af, bc, de, hl 1A7C: 1A7C: up_print_some_text 1A7C: 42 ld b,d ; b = top row 1A7D: 51 ld d,c ; d = c = cols retten 1A7E: 4B ld c,e ; c = left col 1A7F: CDF104 call print_locate ; set text location 1A82: 0600 ld b,0 1A84: 4A ld c,d ; bc = cols 1A85: 1A85: CD8205 call print_find_word_wrap ; HL BC -- DE 1A88: 1A88: A7 and a 1A89: EB ex hl,de 1A8A: ED52 sbc hl,de 1A8C: 4D44 ld bc,hl ; bc = text len 1A8E: EB ex hl,de 1A8F: CDD304 call print_text_hlbc 1A92: 09 add hl,bc 1A93: C9 ret 1A94: 1A94: 1A94: 1A94: 1A94: 1A94: ; --------------------------------------------------------- 1A94: ; print first or additional button 1A94: ; 1A94: ; Saves pixel to heap -> IX 1A94: ; The box.in is either the box for the main text including the buttons row 1A94: ; or the box for the remaining buttons only. 1A94: ; In either case E = left column and C = cols are ok, the top row is calculated 1A94: ; from the bottom row (D.new=D.old+B.old-B.new) and rows is set to 1 (B.new=1). 1A94: ; 1A94: ; in: hl -> text, delimited with 0-byte 1A94: ; de = top/left corner of a box 1A94: ; bc = rows/cols of a box 1A94: ; out: de = top/left corner of box 1A94: ; bc = rows/cols of box 1A94: ; mod: af,c 1A94: 1A94: alert_add_button: 1A94: 1A94: ; calc box.top if this is the first button 1A94: ; (for subsequent buttons this is a nop) 1A94: 7A ld a,d ; top 1A95: 80 add b ; top + rows 1A96: 3D dec a 1A97: 57 ld d,a 1A98: 1A98: E5 push hl ; hl 1A99: D5 push de ; de 1A9A: 1A9A: 7B ld a,e ; box.left 1A9B: 81 add c ; box.cols 1A9C: 5F ld e,a ; e = box.right 1A9D: CDAD05 call print_calc_print_width ; c = text.pixels; b = 0 1AA0: 41 ld b,c ; b = text.pixels 1AA1: 1AA1: 78 ld a,b ; text.pixels 1AA2: 3D dec a 1AA3: F607 or 7 1AA5: 3C inc a 1AA6: 67 ld h,a ; h = text.pixels, expanded to cell boundary 1AA7: 1AA7: 0F rrca 1AA8: 0F rrca 1AA9: 0F rrca 1AAA: 4F ld c,a ; c = button.cols (cells) 1AAB: 1AAB: 7B ld a,e ; box.right 1AAC: 91 sub c ; -button.cols 1AAD: 5F ld e,a ; e = button.left (cells) 1AAE: 1AAE: 7C ld a,h ; a = text.pixels (expanded) 1AAF: 90 sub b ; a = text.pixels (expanded) -text.pixels (exact) = padding 1AB0: 1F rra ; a = padding/2 = padding.left (pixels) 1AB1: 47 ld b,a ; b = padding.left (pixels) 1AB2: 1AB2: 7B ld a,e ; a = button.left (cells) 1AB3: 87 add a 1AB4: 87 add a 1AB5: 87 add a ; a = button.left (pixels) 1AB6: 80 add b ; a = button.left + padding.left = start of text 1AB7: CD2105 call print_setcol 1ABA: 7A ld a,d 1ABB: CD0905 call print_setrow 1ABE: 1ABE: 0601 ld b,1 ; bc = button.cols/rows 1AC0: 1AC0: CD2A1A call alert_save_pixels 1AC3: 1AC3: 7B ld a,e ; a = button.left 1AC4: D1 pop de ; de = box.top/left in = out 1AC5: 93 sub e ; button.left - box.left = remaining box.width 1AC6: 3D dec a ; 1 cell spacing 1AC7: 4F ld c,a ; c = remaining_box.cols 1AC8: 1AC8: E1 pop hl ; hl -> text 1AC9: C3C204 jp print_text_hl 1ACC: 1ACC: 1ACC: 1ACC: ; --------------------------------------------------- 1ACC: ; Remove requester / Restore screen contents 1ACC: ; 1ACC: ; restores all pixels found on the heap up to and including 1ACC: ; the first attributes chunk 1ACC: ; 1ACC: ; in: -- 1ACC: ; out: -- 1ACC: ; mod: af 1ACC: 1ACC: close_alert: 1ACC: 1ACC: #if 0 1ACC: rst save_registers 1ACC: 1ACC: ca3 call mem_hpeek_de 1ACC: inc de 1ACC: inc de 1ACC: inc de 1ACC: ld a,(de) 1ACC: cp $58 1ACC: jp nc,scr_restore_attributes 1ACC: call scr_restore_pixels 1ACC: jr ca3 1ACC: 1ACC: #else 1ACC: 1ACC: D7 rst save_registers 1ACD: E7 rst vip 1ACE: 1ACE: 06 ca3 db hpeek ; handle 1ACF: 636312 db incr, incr, peek ; first word from data 1AD2: 030058E6 db number, $00, $58, ge ; compare against attr addr in screen 1AD6: 2D07 db bra_if, ca_attr-$ 1AD8: 36 db opcode 1AD9: 3C0D dw v_restore_pixels 1ADB: 2AF3 db bra, ca3-$ 1ADD: 1ADD: 69 ca_attr db to_real 1ADE: C37B0D jp scr_restore_attributes 1AE1: #endif 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: 1AE1: #include "alert.ass" 1AE1: 1AE1: ; -------------------------------------------------------- 1AE1: ; Keyboard-Routinen 1AE1: ; -------------------------------------------------------- 1AE1: 1AE1: ; -------------------------------------------------------- 1AE1: ; Tastatur-Tabellen 1AE1: ; -------------------------------------------------------- 1AE1: 1AE1: keycode_illegal equ 0 ; illegal codes 1AE1: keycode_cshift equ keycode_illegal ; single shift key 1AE1: keycode_sshift equ keycode_illegal ; single shift key 1AE1: 1AE1: keycode_edit equ 1 1AE1: keycode_capslock equ 2 1AE1: keycode_video equ 3 1AE1: keycode_rvideo equ 4 1AE1: keycode_left equ 5 1AE1: keycode_down equ 6 1AE1: keycode_up equ 7 1AE1: keycode_right equ 8 1AE1: keycode_graphics equ 9 1AE1: keycode_delete equ 10 1AE1: 1AE1: keycode_cshift_space equ 11 ; caps shift + space = Break 1AE1: keycode_cshift_sshift equ 12 ; caps shift + symbol shift = Extended Mode 1AE1: 1AE1: keycode_return equ 13 1AE1: poundsterling equ 96 1AE1: 1AE1: 1AE1: ; Unshifted Keys: 1AE1: 00 defb 0 ; => Übersetzung 0 -> 0 1AE2: 00 keys: defb keycode_cshift 1AE3: 7A786376 1AE7: 61736466 1AEB: 67 defm "zxcv", "asdfg" 1AEC: 71776572 1AF0: 74313233 1AF4: 3435 defm "qwert", "12345" 1AF6: 30393837 1AFA: 36706F69 1AFE: 7579 defm "09876", "poiuy" 1B00: 0D defb keycode_return 1B01: 6C6B6A68 1B05: 20 defm "lkjh", " " 1B06: 00 defb keycode_sshift 1B07: 6D6E62 defm "mnb" 1B0A: 1B0A: ; Key + Symbol Shift: 1B0A: 00 skeys: defb keycode_cshift 1B0B: 3A603F2F defb ':', poundsterling, '?', '/' 1B0F: 7E7C5C7B 1B13: 7D717765 1B17: 3C3E2140 1B1B: 232425 defm "~|\{}", "qwe<>", "!@#$%" 1B1E: 5F292827 1B22: 26 defm "_)('&" 1B23: 223B495D 1B27: 5B defm '";I][' 1B28: 0D defb keycode_return 1B29: 3D2B2D5E 1B2D: 20 defm "=+-^", " " 1B2E: 00 defb keycode_sshift 1B2F: 2E2C2A defm ".,*" 1B32: 1B32: ; Key + Caps Shift: 1B32: 00 ckeys: defb keycode_cshift 1B33: 5A584356 1B37: 41534446 1B3B: 47515745 1B3F: 5254 defm "ZXCV", "ASDFG", "QWERT" 1B41: 01020304 1B45: 05 defb keycode_edit, keycode_capslock, keycode_video, keycode_rvideo, keycode_left 1B46: 0A090807 1B4A: 06 defb keycode_delete, keycode_graphics, keycode_right, keycode_up, keycode_down 1B4B: 504F4955 1B4F: 59 defm "POIUY" 1B50: 0D defb keycode_return 1B51: 4C4B4A48 defm "LKJH" 1B55: 0B defb keycode_cshift_space 1B56: 0C defb keycode_cshift_sshift 1B57: 4D4E42 defm "MNB" 1B5A: 1B5A: keys_end: 1B5A: 1B5A: 1B5A: 1B5A: ; -------------------------------------------------------- 1B5A: ; Initialisierung: No Action 1B5A: ; Ann.: Data-Bereich wird bei Systemstart genullt. 1B5A: ; "irpt_scan_keyboard" muss in der Interrupt-Routine aufgerufen werden. 1B5A: ; 1B5A: ; in: -- 1B5A: ; out: -- 1B5A: ; mod: -- 1B5A: 1B5A: init_keyboard: 1B5A: C9 ret 1B5B: 1B5B: 1B5B: 1B5B: ; -------------------------------------------------------- 1B5B: ; Flush Input und warte auf eine neue Taste 1B5B: ; 1B5B: ; Der Tastaturpuffer wird geleert und es wird gewartet, 1B5B: ; bis eine evtl. noch gedrückte Taste gelöst wird. 1B5B: ; Erst danach wird auf eine neue Taste gewartet. 1B5B: ; 1B5B: ; Diese Routine sollte benutzt werden, wenn das Programm 1B5B: ; überraschende Eingaben erwartet, z.B. nach "Scroll?" 1B5B: ; 1B5B: ; in: -- 1B5B: ; out: -- 1B5B: ; mod: af 1B5B: 1B5B: wait_newkey: 1B5B: CD651B call flush_inkey 1B5E: ;jr wait_inkey 1B5E: 1B5E: 1B5E: 1B5E: ; -------------------------------------------------------- 1B5E: ; Lese Zeichen aus Tastaturpuffer: 1B5E: ; Wartet bis Zeichen verfügbar. 1B5E: ; Ansonsten wie "get_inkey". 1B5E: ; 1B5E: ; in: -- 1B5E: ; out: a: Zeichen aus Tastaturpuffer 1B5E: ; mod: af 1B5E: 1B5E: wait_inkey: 1B5E: CD751B call get_inkey 1B61: C0 ret nz ; -> ret nz & a!=0 1B62: 76 halt 1B63: 18F9 jr wait_inkey 1B65: 1B65: 1B65: 1B65: ; -------------------------------------------------------- 1B65: ; Lösche Tastaturpuffer und warte, bis keine Taste mehr gedrückt ist. 1B65: ; 1B65: ; in: -- 1B65: ; out: -- 1B65: ; mod: af 1B65: 1B65: flush_inkey: 1B65: 3A375B ld a,(key_oldkey) ; zuerst key_oldkey lesen 1B68: D9 exx 1B69: 210000 ld hl,0 1B6C: 22355B ld (key_inkey),hl ; dann key_inkey löschen 1B6F: D9 exx 1B70: A7 and a 1B71: C8 ret z 1B72: 76 halt 1B73: 18F0 jr flush_inkey 1B75: 1B75: 1B75: 1B75: ; -------------------------------------------------------- 1B75: ; Lese Zeichen aus Tastaturpuffer: 1B75: ; 1B75: ; Es wird entweder 0 (nokey), ein druckbares Zeichen oder ein Controlcode zurückgeliefert. 1B75: ; Controlcodes sind wie oben definiert. 1B75: ; Druckbare Zeichen außer "poundsterling" sind alle 7-Bit-Ascii. 1B75: ; 1B75: ; in: -- 1B75: ; out: a: Zeichen aus Tastaturpuffer oder 0 (nokey) 1B75: ; f: z-Flag zeigt an, ob a=0 (nokey) oder a=Zeichencode 1B75: ; mod: af 1B75: 1B75: get_inkey: 1B75: E5 push hl 1B76: 1B76: ; hole Tastencode 1B76: 2A355B ld hl,(key_inkey) 1B79: 7D ld a,l 1B7A: 6C ld l,h 1B7B: 2600 ld h,0 1B7D: 22355B ld (key_inkey),hl 1B80: 1B80: ; Konvertiere Tastencode in Zeichencode: 1B80: 21E11A ld hl,keys -1 1B83: FE41 cp $41 ; unshifted? 1B85: 3808 jr c,kfs_x ; ja 1B87: D618 sub 24 ; sshift_mask - 40 1B89: FE69 cp $81-24 ; mit symbol shift? 1B8B: 3802 jr c,kfs_x ; ja 1B8D: D618 sub 24 ; sonst mit caps shift 1B8F: 1B8F: 85 kfs_x add l ; hl += a 1B90: 6F ld l,a 1B91: 3001 jr nc,$+3 1B93: 24 inc h 1B94: 1B94: 7E ld a,(hl) ; hole Zeichencode 1B95: 1B95: E1 pop hl 1B96: A7 and a ; -> ret z / ret nz 1B97: C9 ret 1B98: 1B98: 1B98: ; -------------------------------------------------------- 1B98: ; Bis zu drei gleichzeitig gedrückte Tasten werden sinnvoll behandelt: 1B98: ; 1B98: ; - keine Taste Trivial 1B98: ; 1B98: ; - eine Shifttaste wird nicht gepostet 1B98: ; - eine normale Taste wird gepostet 1B98: ; 1B98: ; - beide Shifttasten => normale Taste "Symbolshift" + Caps-Shiftflag 1B98: ; - eine normale Taste + eine Shifttaste => normale Taste + entsprechendes Shiftflag 1B98: ; - zwei normale Tasten Ann.: Überlappung von Tastenaschlägen bei schnellem Tippen: 1B98: ; Die die bisher gedrückte Taste wird als gelöst betrachtet 1B98: ; und die neue gepostet 1B98: ; - zwei normale Tasten + eine Shifttaste dito, nur mit zus. Shiftflag 1B98: ; - eine normale Taste + beide Shifttasten dito, "Symbolshift" wird als normale Taste behandelt 1B98: 1B98: 1B98: 1B98: ; Puffer für bis zu 2 Zeichen zur Übergabe der Tastenscancodes an die Applikation: 1B98: 1B98: key_inkey data 2 ; nokey (0) oder Scancode [1..40] + sshift ($40) + cshift ($80) 1B98: 1B98: 1B98: 1B98: ; Eine Zelle für die beim letzten Scannen erkannte Taste: 1B98: ; 1B98: ; Shifttasten werden als Flags im Tastencode gespeichert und für die gesamte Dauer der Taste 1B98: ; (Autorepeats) so angewandt, wie sie zum Zeitpunkt des Drückens der Taste aktiv waren. 1B98: 1B98: key_oldkey data 1 ; 0 = no Key; sonst: Keycode [1..40] + Shift-Flags 1B98: 1B98: nokey equ 0 ; Zelle leer 1B98: cshift_scancode equ 1 ; bei range [1..40] 1B98: sshift_scancode equ 37 ; bei range [1..40] 1B98: 1B98: sshift_mask equ $40 ; Symbol Shift war zum Drückzeitpunkt aktiv 1B98: cshift_mask equ $80 ; Caps Shift war zum Drückzeitpunkt aktiv 1B98: sshift_bit equ 6 1B98: cshift_bit equ 7 1B98: 1B98: 1B98: ; Timer für Entprellschutz und Autorepeat: 1B98: ; 1B98: ; startdelay + guardtime .. startdelay => Entprellschutz 1B98: ; startdelay .. 0 => Wartezeit bis zum ersten Autorepeat 1B98: ; repeatdelay .. 0 => Wartezeit bis zu weiteren Autorepeats 1B98: 1B98: key_timer data 1 ; Countdown für Guardtime und bis Autorepeat 1B98: 1B98: key_guardtime equ 2 ; 2/50 sec. Entprellschutzzeit 1B98: key_startdelay equ 10 ; 10/50 sec. Delay bis zum ersten Autorepeat 1B98: key_repeatdelay equ 4 ; 4/50 sec. Delay bis zu weiteren Repeats 1B98: 1B98: 1B98: 1B98: 1B98: 1B98: 1B98: 1B98: ; ------------------------------------------------ 1B98: ; Scan Keyboard (Interruptroutine) 1B98: ; in: -- 1B98: ; out: -- 1B98: ; mod: af, bc, de, hl 1B98: 1B98: 1B98: irpt_scan_keyboard: 1B98: 1B98: ; Prüfe, ob die Guardtime für die zuletzt erkannte Taste noch läuft: 1B98: ; In dieser Zeit, kann die (existierende!) Taste nicht gelöscht werden 1B98: ; und logischerweise auch noch keine Autorepeats erzeugen. 1B98: ; Das gilt für eine normale Taste und max. ein Shiftbit im Tastencode. 1B98: ; Nur wenn key_oldkey nur aus einem Shiftbit ohne eine normale Taste besteht, 1B98: ; kann das andere Shiftbit (-> Extended Mode) oder eine normale Taste dazu kommen, 1B98: ; wobei dann ein Tastenevent nach key_inkey geschrieben werden muss. 1B98: 1B98: 21385B ld hl,key_timer ; hl -> key_timer 1B9B: 3E0A ld a,key_startdelay 1B9D: BE cp (hl) 1B9E: 300C jr nc,isk01 ; timer ≤ startdelay => guardtime abgelaufen 1BA0: 1BA0: ; Guardtime ist noch aktiv: 1BA0: ; => prüfe, ob sie nur für ein Shiftbit gilt: 1BA0: 3A375B ld a,(key_oldkey) ; zugehörige Taste 1BA3: 57 ld d,a ; d = Shiftflag (Ann.: alte Taste = einzelne Shifttaste) 1BA4: E63F and $3f ; w/o Shiftflags 1BA6: 2806 jr z,isk001 ; nokey -> Guardtime nur für einzelne Shifttaste 1BA8: 1BA8: ; Guardtime noch aktiv oder key_inkey nicht frei. 1BA8: ; => Tastatur nicht scannen, weil Änderungen nicht gespeichert werden können. 1BA8: ; Timer runterzählen aber nicht bis 0. (Autorepeat verzögern) 1BA8: 1BA8: isk0 ;ld hl,key_timer 1BA8: 35 dec (hl) ; key_timer-- 1BA9: C0 ret nz 1BAA: 34 inc (hl) ; delay autorepeat 1BAB: C9 ret 1BAC: 1BAC: ; Guardtime abgelaufen ((isk01)) oder 1BAC: ; Guardtime gilt nur für ein einzelnes Shiftbit ((isk001)) 1BAC: ; => Prüfe, ob key_inkey frei ist: 1BAC: ; Solange der Tastenpuffer nicht frei ist, ist das Scannen der Tastatur nutzlos, 1BAC: ; da keine neue Taste oder Autorepeat gespeichert werden. => Exit. 1BAC: 1BAC: 1600 isk01 ld d,0 ; d = neue Tasten = nokey; isk001: d = Shiftbit 1BAE: 3A365B isk001 ld a,(key_inkey+1) 1BB1: A7 and a 1BB2: 20F4 jr nz,isk0 ; Tastenpuffer ist belegt! => Exit 1BB4: 1BB4: 1BB4: ; ---------------------------------- 1BB4: ; Guardtime für alte Taste ist nicht mehr aktiv oder gilt nur für ein enzelnes Shiftbit: 1BB4: ; => Eine neue Taste kann auch gespeichert werden. 1BB4: ; => Scan Keyboard. 1BB4: 1BB4: ;ld d,d ; d = neue Taste + Shiftflags 1BB4: 1E00 ld e,0 ; e = keyboard row number [0..7] 1BB6: 01FEFE ld bc,$fefe ; bc = IO address incl. key row sub address in B 1BB9: 1805 jr isk3 1BBB: 1BBB: ; Schleife über alle Tastenzeilen: 1BBB: 1C isk4 inc e ; e = row number ++ 1BBC: CB00 rlc b ; b = next IO key row sub address 1BBE: 3047 jr nc,isk11 ; fertig 1BC0: 1BC0: ED78 isk3 in a,(c) ; a = new key bits 1BC2: 2F cpl ; pressed keys := '1' 1BC3: E61F and $1f ; mask 5 valid keys 1BC5: 28F4 jr z,isk4 ; no pressed key(s) found 1BC7: 1BC7: ; Tastenzeile enthält gedrückte Tasten: 1BC7: ; f = nc, a = key code, bc=IO address, d = current keys, e = row number, hl = -- 1BC7: 67 ld h,a ; h = key bits 1BC8: 7B ld a,e ; row number 1BC9: 87 add a 1BCA: 87 add a 1BCB: 83 add e ; *5 1BCC: 6F ld l,a ; l = current key code 1BCD: 1BCD: ; Schleife über Tasten (Bits): 1BCD: ; a = --, f = nc, bc = io address, d = current keys, e = row number, h = key bits, l = current key code 1BCD: 2C isk5 inc l ; next key code 1BCE: ;and a ; clear c-flag 1BCE: CB1C rr h ; key bits 1BD0: 30FB jr nc,isk5 ; key not pressed -> try next bit 1BD2: 1BD2: ; Gedrückte Taste gefunden: 1BD2: ; a = --, bc = io address, d = current keys, e = row number, h = key bits, l = new key code 1BD2: ; auf Shifttaste prüfen und ggf. in Shiftflag umwandeln: 1BD2: 7D ld a,l ; new key code 1BD3: FE01 cp cshift_scancode ; caps shift key? 1BD5: 2004 jr nz,isk7 ; no 1BD7: CBFA set cshift_bit,d ; d += cshift 1BD9: 1806 jr isk61 1BDB: FE25 isk7 cp sshift_scancode ; symbol shift key? 1BDD: 200B jr nz,isk8 ; no -> normale Taste in l 1BDF: CBF2 set sshift_bit,d ; d += sshift 1BE1: 1BE1: ; Neue Taste war eine Shifttaste. 1BE1: ; Auf beide Shifttasten prüfen und ggf. durch legalen Code ersetzen: 1BE1: 7A isk61 ld a,d 1BE2: FEC0 cp $c0 ; jetzt beide Shifttasten? 1BE4: 381B jr c,isk6 ; no -> ok -> loop 1BE6: 1BE6: ; Jetzt sind beide Shifttasten gedrückt. 1BE6: ; -> Current key in d durch legalen Code ersetzen 1BE6: ; auf 2 Shifttasten + normale Taste testen 1BE6: CBB2 res sshift_bit,d ; d = alte normale Taste (if any) + Caps Shift Bit 1BE8: 2E25 ld l,sshift_scancode ; l = neue normale Taste "Symbol Shift" 1BEA: ;jr isk8 1BEA: 1BEA: 1BEA: ; ---------------------------------- 1BEA: ; normale Taste l gefunden: 1BEA: 7A isk8 ld a,d ; a = new key 1BEB: E63F and $3f ; w/o shift flag 1BED: 280F jr z,isk10 ; es gibt noch keine andere 'normale Taste' 1BEF: 1BEF: ; 2 normale Tasten (d und l) gefunden: 1BEF: ; Ann.: Durch schnelles Tippen können kurzzeitig zwei Tasten gedrückt sein. 1BEF: ; -> (1) Taste d ist alt und l ist neu => d vergessen, l triggern 1BEF: ; (2) Taste l ist alt und d ist neu => l vergessen, d triggern 1BEF: ; (3) beide Tasten sind neu => Ghostkey (oder abusive usage) 1BEF: ; 1BEF: ; (1), (2) Die Guardtime verhindert, dass diese Stellung beim nächsten Interrupt sofort 1BEF: ; erneut umschaltet, und so mit 50 Hz Tastenevents für diese Tasten erzeugt würden. 1BEF: ; Die Guardtime für diese neue Taste sollte ausreichen, dass die alte Taste tatsächlich 1BEF: ; hochgeht und nach Ablauf der Guardtime tatsächlich nicht mehr unten ist. 1BEF: ; Wenn aber jemand zwei Tasten gedrückt hält, kommt es jeweils nach Ablauf der Guardtime 1BEF: ; zu einem alternierenden Triggern dieser beiden Tasten. 1BEF: ; 1BEF: ; (3) Schnelles Tippen bei konstant gedrückter Shifttaste kann zu 3 Tasten plus Ghostkey führen. 1BEF: ; Wenn Tasten d und l beide neu sind ist eine davon wahrscheinlich einen Ghostkey 1BEF: ; und es gibt eine alte Taste und es ist eine Shifttaste gedrückt. (sonst: abusive usage => egal) 1BEF: ; Da nicht entschieden werden kann, welche der beiden neuen Tasten nur ein Ghostkey ist, 1BEF: ; bleibt nichts weiter übrig, als zu warten, dass die alte Taste hochgeht und der 1BEF: ; Ghostkey somit verschwindet. => keine neue Taste und kein Autorepeat posten, Warten => Exit 1BEF: 1BEF: 3A375B ld a,(key_oldkey) ; alte Taste 1BF2: E63F and $3f ; ohne Shiftbits 1BF4: BD cp l 1BF5: 280A jr z,isk6 ; Taste l ist die alte und geht hoch -> d bleibt d -> loop 1BF7: 1BF7: AA xor d 1BF8: E63F and $3f 1BFA: C0 ret nz ; Taste d und l sind neu => Ghostkey! 1BFB: 1BFB: ; Taste d ist die alte und geht hoch 1BFB: 7A ld a,d ; a = ältere Taste incl. Shiftbits 1BFC: E63F and $3f ; a = ältere Taste 1BFE: 1BFE: ; 1. normale Taste gefunden: 1BFE: AA isk10 xor d ; a = Shiftbits 1BFF: B5 or l ; a = neue Taste incl. Shiftbits 1C00: 57 ld d,a ; d = neue Taste incl. Shiftbits: fertig 1C01: ;jr isk6 ; und weiter nach Tasten suchen 1C01: 1C01: ; Taste abgehandelt, nach weiteren Tasten suchen: 1C01: 7C isk6 ld a,h ; remaining key bits 1C02: A7 and a ; Test for z and clear cy 1C03: 28B6 jr z,isk4 ; keine Tasten mehr drin => nächste Zeile 1C05: 18C6 jr isk5 ; weitere Tasten drin => weiter suchen 1C07: 1C07: 1C07: 1C07: 1C07: ; ---------------------------------- 1C07: ; Keyboardmatrix ist gescannt. 1C07: ; d = new key = Nokey|Tastencode + Noshift|SShift|CShift 1C07: ; old key = Nokey|Tastencode + Noshift|SShift|CShift 1C07: 1C07: 21375B isk11 ld hl,key_oldkey ; hl -> key_oldkey 1C0A: 7A ld a,d ; new key 1C0B: E63F and $3f 1C0D: 200A jr nz,isk111 ; es ist eine normale Taste gedrückt 1C0F: 1C0F: ; Es ist keine Taste oder nur eine Shifttaste gedrückt: 1C0F: ; => kein neues Tastenevent oder Autorepeat 1C0F: ; 1C0F: ; Guardtime noch gültig? 1C0F: ; (old key == new key == Shifttaste) 1C0F: ; timer-- 1C0F: ; Guardtime abgelaufen? 1C0F: ; new key == nokey? 1C0F: ; old key := new key = d = nokey 1C0F: ; timer egal 1C0F: ; new key == shift key? 1C0F: ; (es könnte jetzt auch die andere Shifttaste sein.) 1C0F: ; old key == nokey? 1C0F: ; old key := new key = d = shiftkey 1C0F: ; timer := startdelay + guardtime 1C0F: ; old key != nokey? 1C0F: ; old key := new key = d = shiftkey 1C0F: ; timer-- aber nicht auf 0 1C0F: ; 1C0F: AE xor a,(hl) ; a = old key & set flags 1C10: 72 ld (hl),d ; old key := new key 1C11: 23 inc hl ; hl -> key_timer 1C12: 2094 jr nz,isk0 ; old key != nokey => old key == shiftkey => new key egal => timer-- & exit 1C14: AA xor d ; a = new key & set flags 1C15: C8 ret z ; old key == nokey && new key == nokey => timer egal & exit 1C16: 1C16: ; old key == nokey && new key != nokey 1C16: ; => shiftkey goes down: 1C16: 360C ld (hl),key_startdelay + key_guardtime 1C18: C9 ret 1C19: 1C19: 1C19: ; Es ist eine normale Taste und evtl. eine Shifttaste in d gedrückt: 1C19: ; 1C19: ; neue Taste ohne Shiftbits != alte Taste ohne Shiftbits? 1C19: ; ignore whether old key is still down 1C19: ; neue Taste posten 1C19: ; old key := new key 1C19: ; timer := guardtime 1C19: ; neue Taste ohne Shiftbits == alte Taste ohne Shiftbits? 1C19: ; old key untouched (ignore change of shift keys!) 1C19: ; key_inkey[0] leer? 1C19: ; timer-- 1C19: ; Timer abgelaufen? 1C19: ; Autorepeat posten 1C19: ; timer := repeatdelay 1C19: ; key_inkey[0] nicht leer? 1C19: ; timer-- aber nicht bis 0 1C19: ; 1C19: 7E isk111 ld a,(hl) ; old key 1C1A: AA xor d ; new key 1C1B: E63F and $3f ; w/o shiftbits 1C1D: 2011 jr nz,isk13 ; Haupttaste änderte sich 1C1F: 1C1F: ; Haupttaste blieb gleich: 1C1F: 23 inc hl ; hl-> key_timer 1C20: 35 dec (hl) ; timer-- 1C21: C0 ret nz ; repeatdelay noch nicht abgelaufen => fertig! 1C22: ; Autorepeat, außer wenn inkey buffer nicht ganz leer: 1C22: 3A355B ld a,(key_inkey) ; key_inkey[0] 1C25: A7 and a 1C26: 2802 jr z,isk112 ; inkey buffer leer 1C28: 34 inc (hl) ; noch eine Taste im inkey buffer => delay autorepeat! 1C29: C9 ret 1C2A: ; Autorepeat 1C2A: 3604 isk112 ld (hl),key_repeatdelay ; timer := repeat delay 1C2C: 2B dec hl ; hl -> key_oldkey 1C2D: 56 ld d,(hl) ; d = old key with with old shift flags 1C2E: 1804 jr isk14 ; post it & exit 1C30: 1C30: ; Haupttaste änderte sich => neue Haupttaste 1C30: 72 isk13 ld (hl),d ; old key := new key incl. new shift flags 1C31: 23 inc hl ; hl -> key_timer 1C32: 360C ld (hl),key_startdelay + key_guardtime 1C34: ;jr isk14 ; post it & exit 1C34: 1C34: ; post key in d: 1C34: 21355B isk14 ld hl,key_inkey ; hl -> key_inkey[0] 1C37: 7E ld a,(hl) 1C38: A7 and a 1C39: 2801 jr z,$+3 ; key_inkey[0] ist frei; sonst 1C3B: 23 inc hl ; hl -> key_inkey[1] 1C3C: 72 ld (hl),d ; post new key 1C3D: C9 ret 1C3E: 1C3E: 1C3E: 1C3E: 1C3E: 1C3E: 1C3E: #include "keyboard.ass" 1C3E: 1C3E: 1C3E: ; -------------------------------------------------------- 1C3E: ; IC Tester I/O 1C3E: ; -------------------------------------------------------- 1C3E: 1C3E: io_pins data 1 ; Anzahl Pins IC gesamt (-> nur gerade Werte) 1C3E: io_flags data 1 1C3E: io_flag_irpt equ 7 ; io_flags.bit(7) = enable pin display update on interrupt 1C3E: 1C3E: io_bits_table data 0 ; io pin state table: 1C3E: 1C3E: io_bits_l data 0 ; leftside pins: bit 0=top 1C3E: io_bits_A8 data 4 ; pin 1..8 top 1C3E: io_bits_A9 data 4 ; pin 9..16 middle 1C3E: io_bits_A10 data 4 ; pin 17..24 bottom 1C3E: 1C3E: io_bits_r data 0 ; rightside pins: bit 7=top 1C3E: io_bits_A11 data 4 ; pin 25..32 bottom 1C3E: io_bits_A12 data 4 ; pin 33..40 middle 1C3E: io_bits_A13 data 4 ; pin 41..48 top 1C3E: 1C3E: io_offset_out equ 0 ; offset +0: out value 1C3E: io_offset_in equ 2 ; offset +2: input value 1C3E: io_offset_new equ 0 ; offset +0: new (to be displayed) value 1C3E: io_offset_old equ 1 ; offset +1: old (displayed) value 1C3E: 1C3E: io_bits_data_size equ 4 1C3E: io_bits_table_size equ 4*6 1C3E: 1C3E: ; where to display graphics: 1C3E: ic_middle equ 24 ; 23|24 1C3E: 1C3E: ic_col_lout equ ic_middle-8 ; linke Seite: obits 1 char 1C3E: ic_col_ltype equ ic_middle-7 ; pin type: 2 char 1C3E: ic_col_lin equ ic_middle-5 ; ibits 1 char 1C3E: ic_col_lname equ ic_middle-4 ; pin name: 4 char 1C3E: 1C3E: ic_col_rname equ ic_middle+0 ;Rechte Seite: pin name: 4 char 1C3E: ic_col_rin equ ic_middle+4 ; ibits 1 char 1C3E: ic_col_rtype equ ic_middle+5 ; pin type: 2 char 1C3E: ic_col_rout equ ic_middle+7 ; obits 1 char 1C3E: 1C3E: ic_pin_name_sz equ 6 ; max. 5 char + terminating $00 1C3E: ic_pin_name data 48 * ic_pin_name_sz 1C3E: ic_pin_type data 48 1C3E: 1C3E: ic_pin_type_unknown equ 0 1C3E: ic_pin_type_gnd equ 1 1C3E: ic_pin_type_vcc equ 2 1C3E: ic_pin_type_input equ 3 1C3E: ic_pin_type_output equ 4 1C3E: ic_pin_type_io equ 5 1C3E: ic_pin_type_oK equ 6 1C3E: ic_pin_type_3state equ 7 1C3E: ic_pin_type_nc equ 8 1C3E: 1C3E: 1C3E: 1C3E: 1C3E: 1C3E: ; -------------------------------------------------------- 1C3E: ; in: a = pin 1C3E: ; out: hl -> pin type 1C3E: ; a = pin type 1C3E: ; mod: af, hl 1C3E: 1C3E: get_pin_type: 1C3E: 21735C ld hl,ic_pin_type 1C41: 85 add l 1C42: 6F ld l,a 1C43: #if ic_pin_type/256 != (ic_pin_type+47)/256 1C43: ld a,(hl) 1C43: ret nc 1C43: inc h 1C43: #endif 1C43: 7E ld a,(hl) 1C44: C9 ret 1C45: 1C45: 1C45: 1C45: ; -------------------------------------------------------- 1C45: ; in: a = pin 1C45: ; b = type 1C45: ; out: hl -> pin type 1C45: ; mod: af, hl 1C45: 1C45: set_pin_type: 1C45: 21735C ld hl,ic_pin_type 1C48: 85 add l 1C49: 6F ld l,a 1C4A: #if ic_pin_type/256 != (ic_pin_type+47)/256 1C4A: jr nc,$+3 1C4A: inc h 1C4A: #endif 1C4A: 70 ld (hl),b 1C4B: C9 ret 1C4C: 1C4C: 1C4C: 1C4C: ; -------------------------------------------------------- 1C4C: ; Set pin type for current pin 1C4C: ; and update display for this pin 1C4C: ; 1C4C: ; in: -- 1C4C: ; out: -- 1C4C: ; mod: 1C4C: 1C4C: ic_set_pin_type_for_current_pin: 1C4C: 5F ld e,a ; typ retten 1C4D: CD241D call calc_pin_from_hilight ; a = pin 1C50: 43 ld b,e ; b = typ 1C51: 5F ld e,a ; pin retten 1C52: CD451C call set_pin_type 1C55: 7B ld a,e 1C56: 180E jr ic_draw_pin_type 1C58: 1C58: 1C58: 1C58: ; -------------------------------------------------------- 1C58: ; Draw pin type for all pins 1C58: 1C58: ic_draw_all_pin_types: 1C58: 3E2F ld a,47 1C5A: F5 icdap1 push af 1C5B: CD661C call ic_draw_pin_type 1C5E: F1 pop af 1C5F: 3D dec a 1C60: F8 ret m 1C61: 18F7 jr icdap1 1C63: 1C63: 1C63: 1C63: ; -------------------------------------------------------- 1C63: ; in: -- 1C63: 1C63: ic_draw_pin_type_for_current_pin: 1C63: CD241D call calc_pin_from_hilight ; a = pin 1C66: ;jr ic_draw_pin_type 1C66: 1C66: 1C66: 1C66: ; -------------------------------------------------------- 1C66: ; in: a = pin [0..47] 1C66: 1C66: ic_draw_pin_type: 1C66: F5 push af ; sp: pin no. 1C67: 11BC1C ld de,ic_pin_type_text_l 1C6A: 1C6A: 0E11 ld c,ic_col_ltype ; c=col 1C6C: FE18 cp 24 1C6E: 3808 jr c,icdp1 ; pin _is_ left side => calues ok 1C70: 1C70: ; pin is on right side => adjust values 1C70: 11A11C ld de,ic_pin_type_text_r 1C73: 2F cpl ; a = -1 -pin_no 1C74: C630 add 48 ; a = 47 -pin_no 1C76: 0E1D ld c,ic_col_rtype ; c=col 1C78: 1C78: 47 icdp1 ld b,a ; b=row 1C79: 1C79: CD480E call calc_pixel_hl_for_row_b_col_c 1C7C: 1C7C: 220C5B ld (print_hl),hl ; locate text vdu 1C7F: 3E80 ld a,$80 1C81: 320E5B ld (print_c),a 1C84: 3E68 ld a,black+cyan_paper+bright ; set attr 1C86: 320F5B ld (print_attr),a 1C89: 1C89: 010201 ld bc,256*1 + 2 ; rows=2, cols=1 1C8C: CD410C call clear_pixels 1C8F: 1C8F: F1 pop af ; pin no. 1C90: CD3E1C call get_pin_type ; -> a = type 1C93: 3D dec a 1C94: F8 ret m ; typ 0 = unknown => no text 1C95: 1C95: ; de still points to either ic_pin_type_text_l or ic_pin_type_text_r 1C95: ; access and print message for pin type A: 1C95: EB ex hl,de ; hl -> offset-to-message table 1C96: 85 add l 1C97: 6F ld l,a ; hl -> offset-to-message byte 1C98: 86 add (hl) 1C99: 6F ld l,a 1C9A: D2C204 jp nc,print_text_hl 1C9D: 24 inc h 1C9E: C3C204 jp print_text_hl 1CA1: 1CA1: 1CA1: #if $/256 != ($+7)/256 1CA1: defs 256-$%256 1CA1: #endif 1CA1: ic_pin_type_text_r 1CA1: 08 defb icptr1-$ 1CA2: 09 defb icptr2-$ 1CA3: 0A defb icptr3-$ 1CA4: 0B defb icptr4-$ 1CA5: 0C defb icptr5-$ 1CA6: 0D defb icptr6-$ 1CA7: 0F defb icptr7-$ 1CA8: 11 defb icptr8-$ 1CA9: 1CA9: 9600 icptr1 defb charcode_gnd,0 ; gnd 1CAB: 9700 icptr2 defb charcode_vcc,0 ; vcc 1CAD: 9B00 icptr3 defb charcode_i_right,0 ; input 1CAF: 9A00 icptr4 defb charcode_o_right,0 ; output 1CB1: 9500 icptr5 defb charcode_io,0 ; i/o 1CB3: 999A00 icptr6 defb charcode_oK,charcode_o_right,0 ; output oK 1CB6: 989A00 icptr7 defb charcode_3state,charcode_o_right,0 ; output 3state 1CB9: 6E6300 icptr8 defb "nc",0 ; n.c. 1CBC: 1CBC: 1CBC: #if $/256 != ($+7)/256 1CBC: defs 256-$%256 1CBC: #endif 1CBC: ic_pin_type_text_l 1CBC: 08 defb icptl1-$ 1CBD: 0B defb icptl2-$ 1CBE: 0E defb icptl3-$ 1CBF: 11 defb icptl4-$ 1CC0: 14 defb icptl5-$ 1CC1: 17 defb icptl6-$ 1CC2: 1B defb icptl7-$ 1CC3: 1F defb icptl8-$ 1CC4: 1CC4: 048F9600 icptl1 defb ctl_setcol,128+3*8-(c23-c22+2),charcode_gnd,0 ; gnd 1CC8: 048F9700 icptl2 defb ctl_setcol,128+3*8-(c24-c23+2),charcode_vcc,0 ; vcc 1CCC: 04909A00 icptl3 defb ctl_setcol,128+3*8-(c27-c26+2),charcode_i_left,0 ; input 1CD0: 04909B00 icptl4 defb ctl_setcol,128+3*8-(c28-c27+2),charcode_o_left,0 ; output 1CD4: 048E9500 icptl5 defb ctl_setcol,128+3*8-(c22-c21+2),charcode_io,0 ; i/o 1CD8: 04899B99 1CDC: 00 icptl6 defb ctl_setcol,128+3*8-(c28-c27+c26-c25+4),charcode_o_left,charcode_oK,0 ; output oK 1CDD: 04899B98 1CE1: 00 icptl7 defb ctl_setcol,128+3*8-(c28-c27+c25-c24+4),charcode_o_left,charcode_3state,0 ; output 3state 1CE2: 048B6E63 1CE6: 00 icptl8 defb ctl_setcol,128+3*8-(c111-c110+c100-c99+4),"nc",0 ; n.c. 1CE7: 1CE7: 1CE7: 1CE7: ; -------------------------------------------------------- 1CE7: ; calc. Address and bitmask for pin 1CE7: ; 1CE7: ; in: HL -> array[6] 1CE7: ; A = pin no. [0..47] 1CE7: ; out: HL -> array[n/8] 1CE7: ; A = bitmask 1CE7: ; mod: af, de, hl 1CE7: 1CE7: calc_hl_mask_a_for_pin: 1CE7: FE18 cp 24 ; which side? 1CE9: 3002 jr nc,$+4 ; right-side pins are numbered %76543210 => matches bmasks[] 1CEB: EE07 xor 7 ; left-side pins are numbered %01234567 => reverted bit order 1CED: 1CED: 5F ld e,a ; a retten 1CEE: 0F rrca 1CEF: 0F rrca 1CF0: 0F rrca 1CF1: E607 and 7 1CF3: 85 add l 1CF4: 3001 jr nc,$+3 1CF6: 24 inc h 1CF7: 7B ld a,e ; a = pin no. 1CF8: 1CF8: ; calc_bmask: 1CF8: 112E21 ld de,bmasks 1CFB: E607 and 7 1CFD: 83 add e 1CFE: 5F ld e,a 1CFF: 1A ld a,(de) 1D00: C9 ret 1D01: 1D01: 1D01: 1D01: 1D01: 1D01: 1D01: 1D01: 1D01: ; -------------------------------------------------------- 1D01: ; in: A = pin no. [0..47] 1D01: ; out: HL -> attr 1D01: ; mod: AF, BC, HL 1D01: 1D01: calc_attr_hl_for_name: 1D01: 0E14 ld c,ic_col_lname 1D03: FE18 cp 24 1D05: 3819 jr c,ca1 1D07: 0E18 ld c,ic_col_rname 1D09: 1812 jr ca2 1D0B: 1D0B: calc_attr_hl_for_type: 1D0B: 0E11 ld c,ic_col_ltype 1D0D: FE18 cp 24 1D0F: 380F jr c,ca1 1D11: 0E1D ld c,ic_col_rtype 1D13: 1808 jr ca2 1D15: 1D15: calc_attr_hl_for_obit: 1D15: 0E10 ld c,ic_col_lout ; col 1D17: FE18 cp 24 1D19: 3805 jr c,ca1 ; linke Seite 1D1B: 1D1B: 0E1F ld c,ic_col_rout ; col 1D1D: 2F ca2 cpl ; rechte Seite 1D1E: C630 add 48 1D20: 47 ca1 ld b,a ; row 1D21: C3390E jp calc_attr_hl_for_row_b_col_c 1D24: 1D24: 1D24: 1D24: ; -------------------------------------------------------- 1D24: ; Berechne aus row B und col C die zugehörige Pinnummer 1D24: ; 1D24: ; in: B = row 1D24: ; C = col 1D24: ; out: A = pin [0..47] 1D24: 1D24: calc_pin_from_hilight: 1D24: ED4BA35C ld bc,(ic_hilight_row_col) ; b=row, c=col 1D28: 1D28: calc_pin_from_rowcol: 1D28: 79 ld a,c ; col 1D29: FE18 cp ic_middle ; links der Mitte? 1D2B: 78 ld a,b ; dann pin = row 1D2C: D8 ret c ; ja: linke Seite 1D2D: 3E2F ld a,47 1D2F: 90 sub b ; sonst rechte Seite 1D30: C9 ret ; pin = 47 - row 1D31: 1D31: 1D31: 1D31: test_col_c_is_obit: 1D31: 79 ld a,c 1D32: FE10 cp ic_col_lout ; z -> ja 1D34: C8 ret z 1D35: FE1F cp ic_col_rout ; z -> ja 1D37: C9 ret 1D38: 1D38: test_col_c_is_name: 1D38: 79 ld a,c 1D39: FE14 cp ic_col_lname ; z -> ja 1D3B: C8 ret z 1D3C: FE18 cp ic_col_rname ; z -> ja 1D3E: C9 ret 1D3F: 1D3F: test_col_c_is_type: 1D3F: 79 ld a,c 1D40: FE11 cp ic_col_ltype ; z -> ja 1D42: C8 ret z 1D43: FE1D cp ic_col_rtype ; z -> ja 1D45: C9 ret 1D46: 1D46: 1D46: ; -------------------------------------------------------- 1D46: ; Lösche aktuelles Highlight auf Pin, Name oder Type-Feld 1D46: ; 1D46: ; in: -- 1D46: ; out: -- 1D46: ; mod: AF 1D46: 1D46: ic_hilight_row_col data 0 ; for ld bc,(ic_hilight_row_col) 1D46: ic_hilight_col data 1 1D46: ic_hilight_row data 1 1D46: ic_hilight_size_attr data 0 ; for ld de,(ic_hilight_size_attr) 1D46: ic_hilight_size data 1 1D46: ic_hilight_attr data 1 1D46: 1D46: ic_clear_hilight: 1D46: D9 exx 1D47: 1D47: ED5BA55C ld de,(ic_hilight_size_attr) ; d=attr, e=size 1D4B: AF xor a 1D4C: BB cp e 1D4D: 280F jr z,icca3 1D4F: 32A55C ld (ic_hilight_size),a ; ic_hilight_size := 0 1D52: ED4BA35C ld bc,(ic_hilight_row_col) ; b=row, c=col 1D56: 1D56: CD390E call calc_attr_hl_for_row_b_col_c ; pres bc, de 1D59: 1D59: 72 icca1 ld (hl),d ; clear field with old attr 1D5A: 2C inc l 1D5B: 1D dec e 1D5C: 20FB jr nz,icca1 1D5E: 1D5E: D9 icca3 exx 1D5F: C9 ret 1D60: 1D60: 1D60: ; -------------------------------------------------------- 1D60: ; Setze Highlight auf Pin, Name oder Type-Feld 1D60: ; 1D60: ; in: B = row 1D60: ; C = col 1D60: ; out: -- 1D60: ; mod: 1D60: 1D60: ic_set_hilight: 1D60: CDAA1D call ic_validate_hilight ; -> e = size 1D63: CD461D call ic_clear_hilight ; clear old 1D66: CD390E call calc_attr_hl_for_row_b_col_c ; hl -> attr ((pres. bcde)) 1D69: 56 ld d,(hl) ; d = old attr 1D6A: 1D6A: ; set hilight: 1D6A: 7B ld a,e ; a = size 1D6B: 36FA icsh1 ld (hl),flashing+bright+red+white_paper 1D6D: 23 inc hl 1D6E: 3D dec a 1D6F: 20FA jr nz,icsh1 1D71: 1D71: ; update ic_hilight: 1D71: ED43A35C ld (ic_hilight_row_col),bc 1D75: ED53A55C ld (ic_hilight_size_attr),de 1D79: C9 ret 1D7A: 1D7A: 1D7A: #if 0 1D7A: ; -------------------------------------------------------- 1D7A: ; Setze Hilight auf ein obit 1D7A: ; 1D7A: ; in: A = pin no. [0..47] 1D7A: ; out: -- 1D7A: ; mod: AF 1D7A: 1D7A: ic_set_hilight_on_obit: 1D7A: 1D7A: ld b,a ; row = pin 1D7A: ld c,ic_col_lout ; col 1D7A: cp 24 1D7A: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1D7A: ld c,ic_col_rout ; col 1D7A: cpl 1D7A: add 48 1D7A: jr ic_set_hilight 1D7A: 1D7A: 1D7A: 1D7A: ; -------------------------------------------------------- 1D7A: ; Setze Hilight auf ein type feld 1D7A: ; 1D7A: ; in: A = pin no. [0..47] 1D7A: ; out: -- 1D7A: ; mod: AF, AF' 1D7A: 1D7A: ic_set_hilight_on_type: 1D7A: ld b,a ; row = pin 1D7A: ld c,ic_col_ltype ; col 1D7A: cp 24 1D7A: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1D7A: ld c,ic_col_rtype ; col 1D7A: cpl 1D7A: add 48 1D7A: jr ic_set_hilight 1D7A: 1D7A: 1D7A: 1D7A: ; -------------------------------------------------------- 1D7A: ; Setze Hilight auf ein name feld 1D7A: ; 1D7A: ; in: A = pin no. [0..47] 1D7A: ; out: -- 1D7A: ; mod: AF 1D7A: 1D7A: ic_set_hilight_on_name: 1D7A: ld b,a ; row = pin 1D7A: ld c,ic_col_lname ; col 1D7A: cp 24 1D7A: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1D7A: ld c,ic_col_rname ; col 1D7A: cpl 1D7A: add 48 1D7A: jr ic_set_hilight 1D7A: #endif 1D7A: 1D7A: 1D7A: ; -------------------------------------------------------- 1D7A: ; Validate data for pin field 1D7A: ; 1D7A: ; in: B=row 1D7A: ; C=col 1D7A: ; out: B = row 1D7A: ; C = vol 1D7A: ; E = field size 1D7A: ; mod: AF, BC, E 1D7A: 1D7A: 01020200 1D7E: 04040404 1D82: 04040404 1D86: 00020201 ic_size_tab defb 1,2,2,0,4,4,4,4, 4,4,4,4,0,2,2,1 1D8A: 10111111 1D8E: 14141414 ic_col0_tab defb $10,$11,$11,$11,$14,$14,$14,$14 ; col0 der jeweiligen felder 1D92: 18181818 1D96: 181D1D1F defb $18,$18,$18,$18,$18,$1d,$1d,$1f 1D9A: 11141414 1D9E: 18181818 ic_next_tab defb $11,$14,$14,$14,$18,$18,$18,$18 ; col0 des nächsten feldes 1DA2: 1D1D1D1D 1DA6: 1D1F1F10 defb $1d,$1d,$1d,$1d,$1d,$1f,$1f,$10 1DAA: 1DAA: ic_validate_hilight: 1DAA: E5 push hl 1DAB: CDCE1D call ic_validate_row 1DAE: CDC11D call ic_validate_col 1DB1: CDB61D call ic_get_size_for_col 1DB4: E1 pop hl 1DB5: C9 ret 1DB6: 1DB6: ic_get_size_for_col: 1DB6: 216A1D ld hl,ic_size_tab-16 1DB9: 79 ld a,c 1DBA: 85 add l 1DBB: 6F ld l,a 1DBC: 5E ld e,(hl) 1DBD: D0 ret nc 1DBE: 24 inc h 1DBF: 5E ld e,(hl) 1DC0: C9 ret 1DC1: 1DC1: ic_validate_col: 1DC1: 218A1D ld hl,ic_col0_tab 1DC4: 79 ld a,c 1DC5: E60F and $0F 1DC7: 85 add l 1DC8: 6F ld l,a 1DC9: 4E ld c,(hl) 1DCA: D0 ret nc ; <- cy vom 'add l' 1DCB: 24 inc h 1DCC: 4E ld c,(hl) 1DCD: C9 ret 1DCE: 1DCE: ic_validate_row: 1DCE: 3A395B ld a,(io_pins) 1DD1: A7 and a 1DD2: 2002 jr nz,$+4 1DD4: 3E30 ld a,48 ; wenn pins=0 dann volle Höhe zulassen 1DD6: 0F rrca 1DD7: 3D dec a ; a = max 1DD8: B8 cp b 1DD9: D0 ret nc ; ret if b is in range 1DDA: CB78 bit 7,b ; test sign to determine side of overflow 1DDC: 47 ld b,a 1DDD: C0 ret nz ; nz => neg => b < 0 => b := max 1DDE: 0600 ld b,0 ; z => pos => b > max => b := 0 1DE0: C9 ret 1DE1: 1DE1: 1DE1: 1DE1: ; -------------------------------------------------------- 1DE1: ; clear hilight on current cell (if any) 1DE1: ; and move down to next cell 1DE1: 1DE1: ic_move_hilight_down: 1DE1: 3E06 ld a,keycode_down 1DE3: ;jr ic_move_hilight 1DE3: 1DE3: 1DE3: 1DE3: ; -------------------------------------------------------- 1DE3: ; clear hilight on current cell (if any) 1DE3: ; and advance according to key in A 1DE3: 1DE3: ic_move_hilight: 1DE3: ED4BA35C ld bc,(ic_hilight_row_col) ; b=row, c=col 1DE7: 1DE7: 21601D ld hl,ic_set_hilight ; preset return address 1DEA: E5 push hl 1DEB: 1DEB: FE07 cp keycode_up 1DED: 281D jr z,ic_up 1DEF: FE06 cp keycode_down 1DF1: 281B jr z,ic_down 1DF3: FE08 cp keycode_right 1DF5: 281B jr z,ic_right 1DF7: FE05 cp keycode_left 1DF9: 2815 jr z,ic_left 1DFB: 1DFB: FE37 cp '7' 1DFD: 280D jr z,ic_up 1DFF: FE36 cp '6' 1E01: 280B jr z,ic_down 1E03: FE38 cp '8' 1E05: 280B jr z,ic_right 1E07: FE35 cp '5' 1E09: 2805 jr z,ic_left 1E0B: 1E0B: C9 ret ; error 1E0C: 1E0C: 05 ic_up dec b 1E0D: C9 ret 1E0E: 1E0E: 04 ic_down inc b 1E0F: C9 ret 1E10: 1E10: 0D ic_left dec c 1E11: C9 ret 1E12: 1E12: ic_right 1E12: 218A1D ld hl,ic_next_tab-$10 1E15: 79 ld a,c 1E16: 85 add a,l 1E17: 6F ld l,a 1E18: 4E ld c,(hl) 1E19: D0 ret nc 1E1A: 24 inc h 1E1B: 4E ld c,(hl) 1E1C: C9 ret 1E1D: 1E1D: 1E1D: 1E1D: ; -------------------------------------------------------- 1E1D: ; Init / Start / Stop IC-Grafik 1E1D: ; Data-Bereich muss bei Systemstart genullt werden. 1E1D: ; 1E1D: ; in: -- 1E1D: ; out: -- 1E1D: ; mod: -- 1E1D: 1E1D: init_pin_display: 1E1D: stop_pin_display: 1E1D: E5 push hl 1E1E: 213A5B ld hl,io_flags 1E21: CBBE res io_flag_irpt,(hl) ; disable Grafik 1E23: E1 pop hl 1E24: C9 ret 1E25: 1E25: start_pin_display: 1E25: F5 push af 1E26: CD451E call ic_detect_size 1E29: F1 pop af 1E2A: ;jr resume_pin_display 1E2A: 1E2A: resume_pin_display: 1E2A: E5 push hl 1E2B: 213A5B ld hl,io_flags 1E2E: CBFE set io_flag_irpt,(hl) ; enable Grafik 1E30: E1 pop hl 1E31: ;jr ic_force_redraw 1E31: 1E31: 1E31: 1E31: ; -------------------------------------------------------- 1E31: ; Erzwinge Neuanzeige der Grafik 1E31: ; 1E31: ; Die Grafik wird auch sofort einmal ausgegeben, 1E31: ; damit die Updateroutine aufgerufen wird, solange noch alle 1E31: ; neuen Bytes != die alten Bytes sind. 1E31: ; 1E31: ; in: -- 1E31: ; out: -- 1E31: ; mod: -- 1E31: 1E31: ic_force_redraw: 1E31: D9 exx 1E32: F5 push af 1E33: 1E33: 213B5B ld hl,io_bits_table 1E36: 060C ld b,io_bits_table_size / 2 1E38: 1E38: 7E icfr1 ld a,(hl) ; a = new state 1E39: 23 inc hl 1E3A: 2F cpl 1E3B: 77 ld (hl),a ; old_state := ~new_state => redraw 1E3C: 23 inc hl 1E3D: 10F9 djnz icfr1 1E3F: 1E3F: CDF41F call ic_update_all_pins_no_exx 1E42: 1E42: F1 pop af 1E43: D9 exx 1E44: C9 ret 1E45: 1E45: 1E45: 1E45: ; -------------------------------------------------------- 1E45: ; Ermittle Pinzahl des eingesetzten ICs: 1E45: ; 1E45: ; Ann.: Corner pinning 1E45: ; Der Pin links-unten muss fest auf 0 liegen 1E45: ; Setzt io_pins entsprechend 1E45: ; 1E45: ; in: -- 1E45: ; out: a = io_pins 1E45: ; mod: af 1E45: 1E45: ic_detect_size: 1E45: CD711F call ic_switch_vcc_off ; all pins -> 0 1E48: C5 push bc 1E49: 0618 ld b,24 1E4B: 1E4B: 78 icds1 ld a,b 1E4C: 3D dec a 1E4D: CD891E call ic_set_pin ; set pin to 1 1E50: 78 ld a,b 1E51: 3D dec a 1E52: CD621E call ic_get_pin ; read pin back 1E55: 2802 jr z,icds2 ; ground jumper found 1E57: 10F2 djnz icds1 1E59: 1E59: ; ground jumper found (n>0) or not found (n=0) => set io_pins 1E59: 78 icds2 ld a,b 1E5A: 87 add a ; *2 1E5B: 32395B ld (io_pins),a 1E5E: 1E5E: C1 pop bc 1E5F: C3711F jp ic_switch_vcc_off ; alle pins wieder 0 1E62: 1E62: 1E62: 1E62: ; --------------------------------------------- 1E62: ; Read pin from test socket 1E62: ; 1E62: ; Liest das Bit sofort direkt vom Testsockel 1E62: ; aktualisiert io_bits_table[byte].in.new 1E62: ; 1E62: ; Anm.: Normalerweise sollte man io_sync_ibits aufrufen 1E62: ; und danach alle Pin-States nur noch aus der Tabelle lesen. 1E62: ; 1E62: ; in: a = pin no. [0..47] 1E62: ; out: z = z/nz = 0/1 1E62: ; mod: af 1E62: 1E62: 1E62: ic_get_pin: 1E62: D9 exx 1E63: 1E63: CDAF1E call ic_calc_ahlbc_for_pin_a_no_exx 1E66: 23 inc hl 1E67: 23 inc hl ; -> io_bits_table[byte].in.new 1E68: ED48 in c,(c) 1E6A: 71 ld (hl),c 1E6B: 1E6B: A1 and c ; ret z/nz 1E6C: 1E6C: D9 exx 1E6D: C9 ret 1E6E: 1E6E: 1E6E: 1E6E: ; --------------------------------------------- 1E6E: ; Set pin on test socket acc. to cy-flag 1E6E: ; 1E6E: ; Schreibt das Bit umgehend zum Testsockel 1E6E: ; Die restlichen Bits des betroffenen Bytes werden aus 1E6E: ; der io_bits_table[].out.new gelesen. Dieses Byte 1E6E: ; wird danach auch aktualisiert. 1E6E: ; 1E6E: ; Anm.: Wenn viele Pins geändert werden sollen, ist es besser, 1E6E: ; diese in io_bits_table[].out.new zu ändern und danach 1E6E: ; io_sync_obits und dann auch io_sync_ibits aufzurufen. 1E6E: ; 1E6E: ; in: a = pin no. [0..47] 1E6E: ; f = c/nc => set/reset 1E6E: ; out: -- 1E6E: ; mod: af 1E6E: 1E6E: ic_set_pin_to_cy: 1E6E: 3819 jr c,ic_set_pin 1E70: ;jr ic_reset_pin 1E70: 1E70: 1E70: 1E70: ; --------------------------------------------- 1E70: ; set/clear/toggle usw. pin a 1E70: ; 1E70: ; ic_reset_pin set pin a to 0 1E70: ; ic_set_pin set pin a to 1 1E70: ; ic_toggle_pin toggle pin a 0 <-> 1 1E70: ; ic_trigger_pin double toggle (0-1-0 or 1-0-1 dep. on current state) 1E70: ; 1E70: ; in: a = pin no. [0..47] 1E70: ; out: -- 1E70: ; mod: af 1E70: 1E70: ic_reset_current_pin: 1E70: CD241D call calc_pin_from_hilight 1E73: 21D01E ld hl,io_sync_ibits 1E76: E5 push hl 1E77: 1E77: ic_reset_pin: 1E77: D9 exx 1E78: CDAF1E call ic_calc_ahlbc_for_pin_a_no_exx 1E7B: 2F cpl ; bmask -> nmask 1E7C: A6 and (hl) 1E7D: 77 ics1: ld (hl),a 1E7E: ED79 ics2: out (bc),a 1E80: D9 exx 1E81: C9 ret 1E82: 1E82: ic_set_current_pin: 1E82: CD241D call calc_pin_from_hilight 1E85: 21D01E ld hl,io_sync_ibits 1E88: E5 push hl 1E89: 1E89: ic_set_pin: 1E89: D9 exx 1E8A: CDAF1E ics3 call ic_calc_ahlbc_for_pin_a_no_exx 1E8D: B6 or (hl) 1E8E: 18ED jr ics1 1E90: 1E90: ic_toggle_current_pin: 1E90: CD241D call calc_pin_from_hilight 1E93: 21D01E ld hl,io_sync_ibits 1E96: E5 push hl 1E97: 1E97: ic_toggle_pin: 1E97: D9 exx 1E98: CDAF1E call ic_calc_ahlbc_for_pin_a_no_exx 1E9B: AE xor (hl) 1E9C: 18DF jr ics1 1E9E: 1E9E: ic_trigger_current_pin: 1E9E: CD241D call calc_pin_from_hilight 1EA1: 21D01E ld hl,io_sync_ibits 1EA4: E5 push hl 1EA5: 1EA5: ic_trigger_pin: 1EA5: D9 exx 1EA6: CDAF1E call ic_calc_ahlbc_for_pin_a_no_exx 1EA9: AE xor (hl) ; toggle 1EAA: ED79 out (bc),a 1EAC: 7E ld a,(hl) ; toggle 1EAD: 18CF jr ics2 1EAF: 1EAF: 1EAF: 1EAF: ; ---------------------------------------------- 1EAF: ; Calculate parameters for accessing pin a: 1EAF: ; 1EAF: ; in: a = pin no [0..47] 1EAF: ; out: a = mask for bit 1EAF: ; bc = io address for byte 1EAF: ; hl -> io_bits_table[byte].out.new 1EAF: ; mod: af, bc, de, hl 1EAF: 1EAF: ic_calc_ahlbc_for_pin_a_no_exx: 1EAF: ic_calc_ahlbc_for_pin_a: 1EAF: 1EAF: 47 ld b,a ; a = b = pin no. 1EB0: 1EB0: ; calc bit mask: 1EB0: E607 and 7 ; a = bit no. 1EB2: 212E21 ld hl,bmasks 1EB5: 85 add a,l 1EB6: 6F ld l,a 1EB7: 4E ld c,(hl) ; c = bit mask for bit 1EB8: 1EB8: ; calc offset in io table 1EB8: 78 ld a,b ; a = b = pin no. 1EB9: E638 and $38 ; a = byte no. * 8 1EBB: 0F rrca ; a = byte no. * 4 1EBC: 1600 ld d,0 1EBE: 5F ld e,a ; de = offset in io table 1EBF: 1EBF: ; calc io sub address 1EBF: 0F rrca 1EC0: 0F rrca ; a = byte no. 1EC1: ;ld h,nmasks/256 == bmasks/256 1EC1: C636 add a,nmasks%256 1EC3: 6F ld l,a 1EC4: 46 ld b,(hl) ; b = io sub addr 1EC5: 1EC5: ; final 1EC5: 213B5B ld hl,io_bits_table 1EC8: 19 add hl,de ; hl -> io_bits_table[byte] 1EC9: 1EC9: 79 ld a,c ; a = bit mask for bit 1ECA: 0EEF ld c,port ; bc = io addr 1ECC: C9 ret 1ECD: 1ECD: 1ECD: 1ECD: ; --------------------------------------------- 1ECD: ; write io_bits_table[].out.new to tester and 1ECD: ; read io_bits_table[].in.new from tester 1ECD: ; 1ECD: ; in: -- 1ECD: ; out: -- 1ECD: ; mod: af 1ECD: 1ECD: io_sync_iobits: 1ECD: CDE41E call io_sync_obits 1ED0: ; jr io_sync_ibits 1ED0: 1ED0: 1ED0: 1ED0: ; --------------------------------------------- 1ED0: ; read io_bits_table[].in.new from tester 1ED0: ; 1ED0: ; in: -- 1ED0: ; out: -- 1ED0: ; mod: af 1ED0: 1ED0: io_sync_ibits: 1ED0: D9 exx 1ED1: 1ED1: 21515B ld hl,io_bits_table + io_bits_data_size*5 + io_offset_in + io_offset_new 1ED4: 11FCFF ld de,-io_bits_data_size 1ED7: 01EFDF ld bc,port_A13 1EDA: 1EDA: ED78 isi1 in a,(c) 1EDC: 77 ld (hl),a 1EDD: 19 add hl,de 1EDE: CB08 rrc b 1EE0: 38F8 jr c,isi1 1EE2: 1EE2: D9 exx 1EE3: C9 ret 1EE4: 1EE4: 1EE4: 1EE4: ; --------------------------------------------- 1EE4: ; write io_bits_table[].out.new to tester 1EE4: ; 1EE4: ; in: -- 1EE4: ; out: -- 1EE4: ; mod: af 1EE4: 1EE4: io_sync_obits: 1EE4: D9 exx 1EE5: 1EE5: 214F5B ld hl,io_bits_table + io_bits_data_size*5 + io_offset_out + io_offset_new 1EE8: 11FCFF ld de,-io_bits_data_size 1EEB: 01EFDF ld bc,port_A13 1EEE: 1EEE: 7E iso1 ld a,(hl) 1EEF: ED79 out (bc),a 1EF1: 19 add hl,de 1EF2: CB08 rrc b 1EF4: 38F8 jr c,iso1 1EF6: 1EF6: D9 exx 1EF7: C9 ret 1EF8: 1EF8: 1EF8: 1EF8: ; --------------------------------------------- 1EF8: ; Prüfe, ob der Tester antwortet 1EF8: ; 1EF8: ; in: -- 1EF8: ; out: a = error code: 0=ok 1EF8: ; f = z/nz = ok/error 1EF8: ; mod: af 1EF8: 1EF8: ic_test_tester_present: 1EF8: CD711F call ic_switch_vcc_off ; -> all pins 0 1EFB: 76 halt ; if no tester attached, then we might read ula bytes 1EFC: ; => wait until ula out of screen$ area 1EFC: CDD01E call io_sync_ibits ; -> io_bits_table[].in.new sollte jetzt nur Nullen enthalten 1EFF: 1EFF: D9 exx 1F00: 213D5B ld hl,io_bits_table+io_offset_in+io_offset_new 1F03: 110400 ld de,io_bits_data_size 1F06: 0606 ld b,6 ; 6 table cells 1F08: 97 sub a 1F09: 1F09: B6 iso3 or (hl) ; table[].in.new = 0 ? 1F0A: 2006 jr nz,iso4 1F0C: 19 add hl,de 1F0D: 10FA djnz iso3 1F0F: 1F0F: ; 6x $00 -> ok! 1F0F: D9 exx 1F10: A7 and a ; ret z 1F11: C9 ret 1F12: 1F12: ; byte != $00 -> error 1F12: F5 iso4 push af ; sp: the byte 1F13: FEFF cp 255 1F15: 200E jr nz,iso5 ; byte is not $FF 1F17: 3E06 ld a,6 1F19: 90 sub b 1F1A: 2009 jr nz,iso5 ; abort not at first byte => tester present but broken 1F1C: F1 pop af ; drop 1F1D: 1F1D: ; Abort beim 1. Byte mit Wert $FF: 1F1D: ; dann wahrscheinlich kein Tester dran 1F1D: 3E03 ld a,error_notester 1F1F: 32305B ld (errno),a 1F22: A7 and a ; ret nz 1F23: D9 exx 1F24: C9 ret 1F25: 1F25: 1F25: ; Tester seems to respond, but not all bits read back are '0': 1F25: 3E06 iso5 ld a,6 1F27: 90 sub b ; b=6 <=> A8 ... b=1 <=> A13 responds != $00 1F28: F5 iso55 push af ; sp: pin group number [0..5] 1F29: 214A1F ld hl,msg_tester_broken 1F2C: CDC818 call set_error_message ; hl -> data 1F2F: E5 push hl 1F30: FDE1 pop iy 1F32: ; patch error msg: 1F32: F1 pop af ; pin group 1F33: C630 add '0' 1F35: FD770A ld (IY+msg_tester_broken_group),a 1F38: F1 pop af ; the byte 1F39: 47 ld b,a 1F3A: CDE820 call calc_hex_char 1F3D: FD771C ld (IY+msg_tester_broken_lo),a 1F40: 78 ld a,b 1F41: CDE420 call calc_hex_char_hi 1F44: FD771B ld (IY+msg_tester_broken_hi),a 1F47: A7 and a ; ret nz 1F48: D9 exx 1F49: C9 ret 1F4A: 1F4A: 50696E20 1F4E: 67726F75 1F52: 70205820 1F56: 72657370 1F5A: 6F6E6473 1F5E: 20776974 1F62: 68202458 1F66: 582E00 msg_tester_broken defm "Pin group X responds with $XX.",0 1F69: msg_tester_broken_group equ 10 ; offset inside msg 1F69: msg_tester_broken_lo equ 28 ; offset inside msg 1F69: msg_tester_broken_hi equ 27 ; offset inside msg 1F69: 1F69: 1F69: 1F69: ; --------------------------------------------- 1F69: ; Switch Tester on: 1F69: ; set pin_47 (Vcc) to 1 1F69: ; 1F69: ; in: -- 1F69: ; out: -- 1F69: ; mod: af 1F69: 1F69: ic_switch_vcc_on: 1F69: 3E2F ld a,47 1F6B: CD891E call ic_set_pin 1F6E: C3D01E jp io_sync_ibits 1F71: 1F71: 1F71: 1F71: ; --------------------------------------------- 1F71: ; Switch Tester off: 1F71: ; set all pins to 0 1F71: ; 1F71: ; in: -- 1F71: ; out: -- 1F71: ; mod: af 1F71: 1F71: ic_switch_vcc_off: 1F71: D9 exx 1F72: 1F72: 97 sub a ; a = 0 1F73: 01EFC0 ld bc,all_ports 1F76: ED79 out (bc),a ; -> all off 1F78: 1F78: 213B5B ld hl,io_bits_table+io_offset_out+io_offset_new 1F7B: 110400 ld de,io_bits_data_size 1F7E: 0606 ld b,6 ; 6 table cells 1F80: 1F80: 77 iso2 ld (hl),a ; table[].out.new := 0 1F81: 19 add hl,de 1F82: 10FC djnz iso2 1F84: 1F84: D9 exx 1F85: C3D01E jp io_sync_ibits 1F88: 1F88: 1F88: 1F88: 1F88: 1F88: 1F88: ; ------------------------------------------------ 1F88: ; 1F88: ; I N T E R R U P T - R O U T I N E 1F88: ; 1F88: ; ------------------------------------------------ 1F88: 1F88: 1F88: 1F88: ; --------------------------------------------- 1F88: ; Display "0" or "1" at screenbyte address hl 1F88: ; 1F88: ; Overwrites entire 8x8 character cell 1F88: ; Does not set attributes 1F88: ; 1F88: ; in: c.bit(0) 1F88: ; hl -> top byte of character cell 1F88: ; out: -- 1F88: ; mod: -- 1F88: 1F88: ic_render_pin_no_exx: 1F88: ic_render_pin: 1F88: F5 push af 1F89: E5 push hl 1F8A: D5 push de 1F8B: 1F8B: 11A01F ld de,char_0 1F8E: CB41 bit 0,c 1F90: 2802 jr z,$+4 1F92: 1EA7 ld e,char_1 % 256 ; de -> char_0 or char_1 1F94: 1F94: ; 1. Byte ($00) einzeln poken 1F94: ;ld a,(de) 1F94: ;ld (hl),a 1F94: 3600 ld (hl),0 1F96: 1F96: ; dann Schleife bis erneut Byte = $00 1F96: 1C icrp1 inc e ; inc de 1F97: 24 inc h ; inc hl: row(n+1) = row(n)+256 1F98: 1A ld a,(de) 1F99: 77 ld (hl),a 1F9A: A7 and a 1F9B: 20F9 jr nz,icrp1 ; bis unterstes Byte == $00 kopiert wurde 1F9D: 1F9D: D1 pop de 1F9E: E1 pop hl 1F9F: F1 pop af 1FA0: C9 ret 1FA1: 1FA1: #if ($-1)/256 != ($+8-1+8-1-1)/256 1FA1: defs 256 - $%256 + 1 1FA1: #endif 1FA1: 1FA1: char_0 equ $-1 1FA1: ;defb %00000000 1FA1: 3C defb %00111100 1FA2: 46 defb %01000110 1FA3: 4A defb %01001010 1FA4: 52 defb %01010010 1FA5: 62 defb %01100010 1FA6: 3C defb %00111100 1FA7: 00 defb %00000000 1FA8: 1FA8: char_1 equ $-1 1FA8: ;defb %00000000 1FA8: 18 defb %00011000 1FA9: 38 defb %00111000 1FAA: 58 defb %01011000 1FAB: 18 defb %00011000 1FAC: 18 defb %00011000 1FAD: 7E defb %01111110 1FAE: 00 defb %00000000 1FAF: 1FAF: 1FAF: 1FAF: ; --------------------------------------------- 1FAF: ; Display "0" or "1" for group of 8 pins 1FAF: ; Renders only changed bits 1FAF: ; Uses rr to advance bit => used for leftside columns 1FAF: ; 1FAF: ; in: hl -> io_pins table cell 1FAF: ; de -> screenbyte 1FAF: ; a = valid bits mask 1FAF: ; out: hl -> next cell = hl+2 1FAF: ; mod: af 1FAF: 1FAF: ic_render_8_pins_left_no_exx: 1FAF: ic_render_8_pins_left: 1FAF: C5 push bc 1FB0: D5 push de 1FB1: 1FB1: 47 ld b,a ; b = valid bits 1FB2: 4E ld c,(hl) ; c = new value 1FB3: 23 inc hl 1FB4: 7E ld a,(hl) ; a = old value 1FB5: 71 ld (hl),c ; update old value cell 1FB6: 23 inc hl 1FB7: E5 push hl 1FB8: 1FB8: A9 xor c ; a = old ^ new = changed bits 1FB9: A0 and b ; a = valid pins only & cy=0 1FBA: EB ex hl,de ; hl -> screenbyte 1FBB: 112000 ld de,32 ; de = screen row offset 1FBE: 1803 jr icr1 1FC0: 1FC0: CB19 icr2 rr c ; next pin 1FC2: 19 add hl,de ; next character row & cy=0 1FC3: 1FC3: CB1F icr1 rr a ; next 'pin changed' flag ((rr a not rra wg. z-flag)) 1FC5: DC881F call c,ic_render_pin_no_exx ; pin changed => draw it 1FC8: 20F6 jr nz,icr2 ; still 'pin changed' flags set 1FCA: 1FCA: E1 pop hl 1FCB: D1 pop de 1FCC: C1 pop bc 1FCD: C9 ret 1FCE: 1FCE: 1FCE: 1FCE: ; --------------------------------------------- 1FCE: ; Display "0" or "1" for group of 8 pins 1FCE: ; Renders only changed bits 1FCE: ; Uses rl to advance bit => used for rightside columns 1FCE: ; 1FCE: ; in: hl -> io_pins table cell 1FCE: ; de -> screenbyte 1FCE: ; a = valid bits mask 1FCE: ; out: hl -> prev cell = hl-2 1FCE: ; mod: af 1FCE: 1FCE: ic_render_8_pins_right_no_exx: 1FCE: ic_render_8_pins_right: 1FCE: C5 push bc 1FCF: D5 push de 1FD0: E5 push hl 1FD1: 1FD1: 47 ld b,a ; b = valid bits 1FD2: 4E ld c,(hl) ; c = new value 1FD3: 23 inc hl 1FD4: 7E ld a,(hl) ; a = old value 1FD5: 71 ld (hl),c ; update old value cell 1FD6: 1FD6: A9 xor c ; a = old ^ new = changed bits 1FD7: A0 and b ; a = valid pins only & cy=0 1FD8: EB ex hl,de ; hl -> screenbyte 1FD9: 112000 ld de,32 ; de = screen row offset 1FDC: ED52 sbc hl,de 1FDE: 1FDE: CB01 icr4 rlc c ; next pin -> bit 0 1FE0: 19 add hl,de ; next character row & cy=0 1FE1: 1FE1: CB17 rl a ; next 'pin changed' flag ((rl a not rla wg. z-flag)) 1FE3: DC881F call c,ic_render_pin ; pin changed => draw it 1FE6: 20F6 jr nz,icr4 ; still 'pin changed' flags set 1FE8: 1FE8: E1 pop hl 1FE9: D1 pop de 1FEA: C1 pop bc 1FEB: 2B dec hl 1FEC: 2B dec hl 1FED: C9 ret 1FEE: 1FEE: 1FEE: 1FEE: ; -------------------------------------------------------- 1FEE: ; Interruptroutine 1FEE: ; 1FEE: ; Update displayed state if IC pins 1FEE: ; Renders changed pins only 1FEE: ; draws io_pins/2 pins per side 1FEE: ; draws 4 columns in total: 1FEE: ; left side: out state to test socket 1FEE: ; left side: in state from test socket 1FEE: ; right side: in state from test socket 1FEE: ; right side: out state to test socket 1FEE: ; Uses data from io_pins table only 1FEE: ; Does not actually read state from tester 1FEE: ; 1FEE: ; in: -- 1FEE: ; out: -- 1FEE: ; mod: af, bc, de, hl 1FEE: 1FEE: irpt_pin_display: 1FEE: 3A3A5B ld a,(io_flags) 1FF1: CB7F bit io_flag_irpt,a 1FF3: C8 ret z 1FF4: ;jr ic_update_all_pins 1FF4: 1FF4: 1FF4: 1FF4: ; --------------------------------------------- 1FF4: ; Update all 4 pin display columns 1FF4: ; Renders only changed bits 1FF4: ; 1FF4: ; in: -- 1FF4: ; out: -- 1FF4: ; mod: af, bc, de, hl 1FF4: 1FF4: ic_update_all_pins_no_exx: 1FF4: ic_update_all_pins: 1FF4: 1FF4: 3A395B ld a,(io_pins) 1FF7: CB2F sra a ; a = pins per side 1FF9: C8 ret z ; pins = 0 1FFA: 1FFA: 01515B ld bc,io_bits_r +io_offset_in +io_bits_data_size*2 ; bc -> right side table, last cell 1FFD: 213B5B ld hl,io_bits_l +io_offset_out ; hl -> left side table, first cell 2000: 2000: 1640 ld d,$40 ; de -> screen, start of upper block 2002: 2002: C5 icr5 push bc ; (sp) -> rightside table cells 2003: 2003: 4F ld c,a ; a = c = remaining pins 2004: CD2221 call calc_rmask 2007: 47 ld b,a ; a = b = mask 2008: 2008: 1E10 ld e,ic_col_lout ; de -> screenbyte 200A: CDAF1F call ic_render_8_pins_left_no_exx ; hl+=2 200D: 200D: 78 ld a,b ; a = mask 200E: 1E13 ld e,ic_col_lin ; de -> screenbyte 2010: CDAF1F call ic_render_8_pins_left_no_exx ; hl+=2 2013: 2013: E3 ex hl,(sp) ; hl -> rightside table cells 2014: 2014: 79 ld a,c ; a = c = remaining pins 2015: CD1A21 call calc_lmask 2018: 47 ld b,a ; a = b = mask 2019: 2019: 1E1C ld e,ic_col_rin ; de -> screenbyte 201B: CDCE1F call ic_render_8_pins_right_no_exx ; hl-=2 201E: 201E: 78 ld a,b ; a = mask 201F: 1E1F ld e,ic_col_rout ; de -> screenbyte 2021: CDCE1F call ic_render_8_pins_right_no_exx ; hl-=2 2024: 2024: E3 ex hl,(sp) ; hl -> leftside table cells 2025: 2025: 7A ld a,d 2026: C608 add 8 2028: 57 ld d,a ; de -> next screen block 2029: 2029: 79 ld a,c 202A: D608 sub 8 ; a = remaining pins 202C: 202C: C1 pop bc 202D: C8 ret z ; remaining pins = 0 202E: 30D2 jr nc,icr5 ; remaining pins > 0 2030: C9 ret ; remaining pins < 0 2031: 2031: 2031: 2031: 2031: 2031: 2031: 2031: #include "pin display.ass" 2031: 2031: 2031: 2031: ; -------------------------------------------------------- 2031: ; System Timer: 2031: ; 2 bytes overflow after approx. 22 min. 2031: 2031: timer_cell data 3 2031: 2031: 2031: 2031: ; -------------------------------------------------------- 2031: ; Initialisierung: No Action 2031: ; Ann.: Data-Bereich wird bei Systemstart genullt. 2031: ; 2031: ; in: -- 2031: ; out: -- 2031: ; mod: -- 2031: 2031: init_timer: 2031: C9 ret 2032: 2032: 2032: 2032: ; -------------------------------------------------------- 2032: ; Interruptroutine 2032: ; 2032: ; in: -- 2032: ; out: -- 2032: ; mod: hl, f 2032: 2032: irpt_timer: 2032: 21A75C ld hl,timer_cell 2035: 34 inc (hl) 2036: C0 ret nz 2037: 23 inc hl 2038: 34 inc (hl) 2039: C0 ret nz 203A: 23 inc hl 203B: 34 inc (hl) 203C: C9 ret 203D: 203D: 203D: #include "timer.ass" 203D: 203D: ; -------------------------------------------------------- 203D: ; Utilities 203D: ; -------------------------------------------------------- 203D: 203D: ; ------------------------------------------------------------ 203D: ; count 0-terminated string length 203D: ; 203D: ; in: hl -> text 203D: ; out: hl -> text (preserved) 203D: ; de = size 203D: ; mod: af, de 203D: 203D: calc_strlen: 203D: 5D54 ld de,hl ; de = hl -> text 203F: 97 sub a 2040: BE sl1 cp (hl) 2041: 23 inc hl 2042: 20FC jr nz,sl1 2044: 37 scf ; hl -> behind 0 2045: ED52 sbc hl,de ; hl = len 2047: EB ex hl,de 2048: C9 ret 2049: 2049: 2049: 2049: 2049: ; ------------------------------------------------------------ 2049: ; print hl as decimal number with auto-sized field width 2049: ; 2049: ; vzdecstr prints with sign 2049: ; decstr prints unsigned 2049: ; 2049: ; in: hl = number 2049: ; de -> text buffer 2049: ; out: de++ 2049: ; mod: af,bc,de,hl 2049: 2049: vzdecstr: 2049: CB7C bit 7,h 204B: 280B jr z,decstr 204D: 3E2D ld a,'-' 204F: 12 ld (de),a 2050: 13 inc de 2051: 2051: 7C ld a,h 2052: 2F cpl 2053: 67 ld h,a 2054: 7D ld a,l 2055: 2F cpl 2056: 6F ld l,a 2057: 23 inc hl 2058: 2058: decstr: 2058: 011027 ld bc,10000 ; print auto-sized 1-5 characters 205B: A7 and a 205C: ED42 sbc hl,bc 205E: 09 add hl,bc 205F: 301D jr nc,decstr5 2061: 2061: 01E803 ld bc,1000 2064: A7 and a 2065: ED42 sbc hl,bc 2067: 09 add hl,bc 2068: 301A jr nc,decstr4 206A: 206A: decstr_max3digits: 206A: 016400 ld bc,100 206D: A7 and a 206E: ED42 sbc hl,bc 2070: 09 add hl,bc 2071: 3017 jr nc,decstr3 2073: 2073: 010A00 ld bc,10 2076: A7 and a 2077: ED42 sbc hl,bc 2079: 09 add hl,bc 207A: 3014 jr nc,decstr2 207C: 1818 jr decstr1 207E: 207E: 207E: ; ------------------------------------------------------------ 207E: ; print unsigned decimal number with fixed amount of digits 207E: ; the number must actually fit in the requested field width, 207E: ; else strange letters are printed. 207E: ; 207E: ; decstr[1..5]: print hl with fixed field width 1..5 digits 207E: ; 207E: ; in: hl = number 207E: ; de->text buffer 207E: ; out: de++ 207E: ; mod: af, bc, de, hl 207E: 207E: decstr5 207E: 011027 ld bc,10000 ; print 5 characters wide 2081: CD9920 call ds 2084: decstr4 2084: 01E803 ld bc,1000 ; print 4 characters wide 2087: CD9920 call ds 208A: decstr3 208A: 016400 ld bc,100 ; print 3 characters wide 208D: CD9920 call ds 2090: decstr2 2090: 010A00 ld bc,10 ; print 2 characters wide 2093: CD9920 call ds 2096: decstr1 2096: 010100 ld bc,1 ; print 1 character wide 2099: 2099: 3E2F ds ld a,'0'-1 209B: A7 and a 209C: 3C ds1 inc a 209D: ED42 sbc hl,bc 209F: 30FB jr nc,ds1 20A1: 09 add hl,bc 20A2: 12 ld (de),a 20A3: 13 inc de 20A4: C9 ret 20A5: 20A5: 20A5: 20A5: ; ------------------------------------------------------------ 20A5: ; print word as 4 hex chars 20A5: ; 20A5: ; in: hl = number 20A5: ; de->text buffer 20A5: ; out: de++ 20A5: ; mod: af 20A5: 20A5: hexstr4: 20A5: E5 push hl 20A6: 7C ld a,h 20A7: CDAC20 call hexstr2 20AA: E1 pop hl 20AB: 7D ld a,l 20AC: ;jr hexstr2 20AC: 20AC: 20AC: 20AC: ; ------------------------------------------------------------ 20AC: ; print byte as 2 hex chars 20AC: ; 20AC: ; in: a = number 20AC: ; de->text buffer 20AC: ; out: de++ 20AC: ; mod: af,de 20AC: 20AC: hexstr2: 20AC: F5 push af 20AD: CDB320 call hexstr1hi 20B0: F1 pop af 20B1: 1804 jr hexstr1 20B3: 20B3: ; ------------------------------------------------------------ 20B3: ; print hex char for the upper nibble 20B3: ; 20B3: ; in: a = number 20B3: ; de->text buffer 20B3: ; out: de++ 20B3: ; mod: af,de 20B3: 20B3: hexstr1hi: 20B3: 1F rra 20B4: 1F rra 20B5: 1F rra 20B6: 1F rra 20B7: ;jr hexstr1 20B7: 20B7: ; ------------------------------------------------------------ 20B7: ; print hex char for the lower nibble 20B7: ; 20B7: ; in: a = number (lower nibble only) 20B7: ; de->text buffer 20B7: ; out: de++ 20B7: ; mod: af,de 20B7: 20B7: hexstr1: 20B7: E60F and $0f 20B9: C630 add '0' 20BB: FE3A cp '9'+1 20BD: 3802 jr c,hs1 20BF: C607 add 7 20C1: 12 hs1 ld (de),a 20C2: 13 inc de 20C3: C9 ret 20C4: 20C4: 20C4: 20C4: ; ------------------------------------------------------------ 20C4: ; print word as 16 binary chars 20C4: ; 20C4: ; in: hl = number 20C4: ; de->text buffer 20C4: ; out: de++ 20C4: ; mod: af 20C4: 20C4: binstr16: 20C4: E5 push hl 20C5: 7C ld a,h 20C6: CDCB20 call binstr8 20C9: E1 pop hl 20CA: 7D ld a,l 20CB: ;jr binstr8 20CB: 20CB: 20CB: 20CB: ; ------------------------------------------------------------ 20CB: ; print byte as 8 binary chars 20CB: ; 20CB: ; in: a = number 20CB: ; de->text buffer 20CB: ; out: de++ 20CB: ; mod: af 20CB: 20CB: binstr8: 20CB: C5 push bc 20CC: 0608 ld b,8 20CE: 4F bs0 ld c,a 20CF: 3E18 bs1 ld a,'0'/2 20D1: CB11 rl c 20D3: 8F adc a,a 20D4: 12 ld (de),a 20D5: 13 inc de 20D6: 10F7 djnz bs1 20D8: C1 pop bc 20D9: C9 ret 20DA: 20DA: 20DA: 20DA: ; ------------------------------------------------------------ 20DA: ; print nibble as 4 binary chars 20DA: ; 20DA: ; in: a = number (lower nibble only) 20DA: ; de->text buffer 20DA: ; out: de++ 20DA: ; mod: af 20DA: 20DA: binstr4: 20DA: C5 push bc 20DB: 0604 ld b,4 20DD: 18EF jr bs0 20DF: 20DF: 20DF: 20DF: 20DF: 20DF: 20DF: 20DF: 20DF: ; --------------------------------------------- 20DF: ; dereference a pointer 20DF: ; 20DF: ; in: hl -> pointer or -> 2-byte value 20DF: ; out: hl = pointer or 2-byte-value 20DF: ; mod: a,hl 20DF: 20DF: deref_hl: 20DF: 7E ld a,(hl) 20E0: 23 inc hl 20E1: 66 ld h,(hl) 20E2: 6F ld l,a 20E3: C9 ret 20E4: 20E4: 20E4: 20E4: ; --------------------------------------------- 20E4: ; Convert hex value (nibble) to hex character 20E4: ; 20E4: ; in: a = lower nibble 20E4: ; out: a = char 20E4: ; mod: af 20E4: 20E4: calc_hex_char_hi: 20E4: 0F rrca 20E5: 0F rrca 20E6: 0F rrca 20E7: 0F rrca 20E8: 20E8: calc_hex_char: 20E8: E60F and $0f 20EA: C630 add '0' 20EC: FE3A cp '9'+1 20EE: D8 ret c ; '0' .. '9' 20EF: C607 add 7 20F1: C9 ret ; 'A' .. 'F' 20F2: 20F2: 20F2: 20F2: ; ------------------------------------- 20F2: ; multiply: hl = b x c 20F2: ; 20F2: ; je kleiner b, desto schneller. 20F2: ; 20F2: ; in: b = n1 20F2: ; c = n2 20F2: ; out: hl 20F2: ; mod: a, bc, hl 20F2: 20F2: mult_bc: 20F2: 78 ld a,b ; a = signifikanter multiplikator 20F3: mult_ac: 20F3: 210000 ld hl,0 ; hl = ergebnis-summierer 20F6: 45 ld b,l ; bc = c = addierter multiplikator 20F7: 20F7: A7 and a ; bei a = 0 sonst kein Abbruch! 20F8: 2005 jr nz,mu1 20FA: C9 ret 20FB: 20FB: mu2 ;and a ; cy muss 0 sein! 20FB: CB11 rl c ; shift left bc 20FD: CB10 rl b 20FF: 20FF: mu1 ;and a ; cy muss 0 sein! 20FF: 1F rra ; cy = nächsthöheres bit, a mit 0 auffüllen 2100: 30F9 jr nc,mu2 ; da a != 0 und jetzt kein bit rausgeschiftet wurde, 2102: ; muss immer noch mind. 1 bit in a sein 2102: 09 add hl,bc 2103: A7 and a ; a jetzt 0 ? 2104: 20F5 jr nz,mu2 ; nein => weiter gehts 2106: C9 ret ; ja => fertig 2107: 2107: 2107: 2107: ; ------------------------------------- 2107: ; calculate mask which includes bit n 2107: ; bit no. is masked with $07 to force legal 2107: ; 2107: ; calc_bmask: bits are counted from right (lsb) to left (msb) %76543210 2107: ; calc_rbmask: bits are counted in reverse order from left to right %01234567 2107: ; 2107: ; in: a = bit no. 2107: ; out: a = mask 2107: ; mod: af 2107: 2107: calc_rbmask: 2107: 2F cpl 2108: 2108: calc_bmask: 2108: E607 and 7 210A: C62E add a,bmasks%256 210C: ;jr crfb2 210C: 210C: E5 crfb2 push hl ; xymasks[a] 210D: 2621 ld h,masks/256 ; h = high byte for all masks[] 210F: 6F ld l,a 2110: 7E ld a,(hl) 2111: E1 pop hl 2112: C9 ret 2113: 2113: 2113: 2113: ; ------------------------------------- 2113: ; calculate mask which excludes bit n 2113: ; bit no. is masked with $07 to force legal 2113: ; 2113: ; calc_nmask: bits are counted from right (lsb) to left (msb) %76543210 2113: ; calc_rnmask: bits are counted in reverse order from left to right %01234567 2113: ; 2113: ; in: a = bit no. 2113: ; out: a = mask 2113: ; mod: af 2113: 2113: calc_rnmask: 2113: 2F cpl 2114: 2114: calc_nmask: 2114: E607 and 7 2116: C636 add a,nmasks%256 ; a < 8 => nmasks[a] 2118: 18F2 jr crfb2 211A: 211A: 211A: 211A: ; ------------------------------------- 211A: ; calculate mask which includes n bits from the left (msb) 211A: ; if bits >= 8 then mask = $ff 211A: ; if bits <= 0 then mask = $00 211A: ; 211A: ; in: a = bits 211A: ; out: a = mask 211A: ; mod: af 211A: 211A: calc_lmask: 211A: FE08 cp 8 211C: 300C jr nc,crfb1 ; a≥8 / a<0 => $ff / $00 211E: C63E add a,lmasks%256 ; a < 8 => lmasks[a] 2120: 18EA jr crfb2 2122: 2122: 2122: 2122: ; ------------------------------------- 2122: ; calculate mask which includes n bits from the right (lsb) 2122: ; if bits >= 8 then mask = $ff 2122: ; if bits <= 0 then mask = $00 2122: ; 2122: ; in: a = bits 2122: ; out: a = mask 2122: ; mod: af 2122: 2122: calc_rmask: 2122: FE08 cp 8 2124: 3004 jr nc,crfb1 ; a≥8 / a<0 => $ff / $00 2126: C646 add a,rmasks%256 2128: 18E2 jr crfb2 212A: 212A: 17 crfb1 rla ; cy = vz 212B: 9F sbc a ; mi => $ff / pl => $00 212C: 2F cpl ; mi => $00 / pl => $ff 212D: C9 ret 212E: 212E: 212E: 212E: #if $/256 != ($+32-1)/256 212E: defs 256 - $%256 212E: #endif 212E: 212E: masks: equ $ 212E: 01020408 2132: 10204080 bmasks defb $01, $02, $04, $08, $10, $20, $40, $80 2136: FEFDFBF7 213A: EFDFBF7F nmasks defb $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f 213E: 0080C0E0 2142: F0F8FCFE lmasks defb $00, $80, $c0, $e0, $f0, $f8, $fc, $fe 2146: 00010307 214A: 0F1F3F7F rmasks defb $00, $01, $03, $07, $0f, $1f, $3f, $7f 214E: 214E: 214E: 214E: 214E: #if 0 214E: ; -------------------------------------------------------- 214E: ; calc. Address and bitmask for bit array 214E: ; 214E: ; in: HL -> array 214E: ; A = bit no. 214E: ; out: HL -> array[n/8] 214E: ; A = bitmask 214E: ; mod: af, hl 214E: 214E: calc_addr_hl_and_mask_a_for_bit: 214E: push de 214E: 214E: ld e,a ; a retten 214E: rrca 214E: rrca 214E: rrca 214E: and $1f 214E: add l 214E: jr nc,$+3 214E: inc h 214E: ld a,e ; a = pin no. 214E: 214E: ; calc_bmask: 214E: ld de,bmasks 214E: and 7 214E: add e 214E: ld e,a 214E: ld a,(de) 214E: 214E: pop de 214E: ret 214E: #endif 214E: 214E: 214E: 214E: 214E: 214E: 214E: 214E: 214E: 214E: #if 0 214E: 214E: ; get bit number for MSB '1' in A 214E: ; in: a = bitarray/mask 214E: ; out: a = bit number [7..0] or a=-1 if a was $00 214E: ; mod: f 214E: ; 214E: up_get_bitno_of_msb: 214E: push bc 214E: ld b,8 214E: up_bn1 rlca 214E: jr c,up_bn2 214E: djnz up_bn1 214E: up_bn2 dec b 214E: ld a,b 214E: pop bc 214E: ret 214E: 214E: ; get bit number for LSB '1' in A 214E: ; in: a = bitarray/mask 214E: ; out: a = bit number [7..0] or a=8 if a was $00 214E: ; mod: f 214E: ; 214E: up_get_bitno_of_lsb: 214E: push bc 214E: ld b,8 214E: up_bn3 rrca 214E: jr c,up_bn4 214E: djnz up_bn3 214E: up_bn4 ld a,8 214E: sub b 214E: pop bc 214E: ret 214E: 214E: 214E: up_get_mask_for_bitno: 214E: and 7 214E: push bc 214E: ld bc,up_sbt 214E: add a,c 214E: ld c,a 214E: ld a,(bc) 214E: pop bc 214E: ret 214E: 214E: #if $/256 != ($+7)/256 214E: defs 256 - ($%256) 214E: #endif 214E: up_sbt defb 1,2,4,8,16,32,64,128 214E: 214E: #endif 214E: 214E: 214E: 214E: 214E: 214E: #include "utilities.ass" 214E: 214E: 214E: 214E: vip_test 214E: E7 rst vip 214F: 9B0D5649 2153: 50205465 2157: 73743A20 215B: 00C2 db string,13,"VIP Test: ",0,print 215D: 215D: ; ≥ 215D: 215D: 0021 db byte, 33 215F: 002C db byte, 44 2161: E6 db ge 2162: 300C db bra_ifnot,vt1-$ 2164: 9B213333 2168: 3E3D3434 216C: 00C2 db string, "!33>=44",0, print 216E: 216E: 0021 vt1 db byte, 33 2170: 0021 db byte, 33 2172: E6 db ge 2173: 2D0C db bra_if,vt2-$ 2175: 9B213333 2179: 3E3D3333 217D: 00C2 db string, "!33>=33",0, print 217F: 217F: 002C vt2 db byte, 44 2181: 0021 db byte, 33 2183: E6 db ge 2184: 2D0C db bra_if,vt3-$ 2186: 9B213434 218A: 3E3D3333 218E: 00C2 db string, "!44>=33",0, print 2190: 2190: ; > 2190: 2190: 0021 vt3 db byte, 33 2192: 002C db byte, 44 2194: E4 db gt 2195: 300B db bra_ifnot,vt24-$ 2197: 9B213333 219B: 3E343400 219F: C2 db string, "!33>44",0, print 21A0: 21A0: 0021 vt24 db byte, 33 21A2: 00D4 db byte, -44 21A4: E4 db gt 21A5: 2D0C db bra_if,vt4-$ 21A7: 9B213333 21AB: 3E2D3434 21AF: 00C2 db string, "!33>-44",0, print 21B1: 21B1: 0021 vt4 db byte, 33 21B3: 0021 db byte, 33 21B5: E4 db gt 21B6: 300B db bra_ifnot,vt5-$ 21B8: 9B213333 21BC: 3E333300 21C0: C2 db string, "!33>33",0, print 21C1: 21C1: 002C vt5 db byte, 44 21C3: 0021 db byte, 33 21C5: E4 db gt 21C6: 2D0B db bra_if,vt6-$ 21C8: 9B213434 21CC: 3E333300 21D0: C2 db string, "!44>33",0, print 21D1: 21D1: ; ≤ 21D1: 21D1: 0021 vt6 db byte, 33 21D3: 002C db byte, 44 21D5: EA db le 21D6: 2D0C db bra_if,vt7-$ 21D8: 9B213333 21DC: 3C3D3434 21E0: 00C2 db string, "!33<=44",0, print 21E2: 21E2: 0021 vt7 db byte, 33 21E4: 0021 db byte, 33 21E6: EA db le 21E7: 2D0C db bra_if,vt8-$ 21E9: 9B213333 21ED: 3C3D3333 21F1: 00C2 db string, "!33<=33",0, print 21F3: 21F3: 002C vt8 db byte, 44 21F5: 0021 db byte, 33 21F7: EA db le 21F8: 300C db bra_ifnot,vt9-$ 21FA: 9B213434 21FE: 3C3D3333 2202: 00C2 db string, "!44<=33",0, print 2204: 2204: ; < 2204: 2204: 0021 vt9 db byte, 33 2206: 002C db byte, 44 2208: E8 db lt 2209: 2D0B db bra_if,vt10-$ 220B: 9B213333 220F: 3C343400 2213: C2 db string, "!33<44",0, print 2214: 2214: 0021 vt10 db byte, 33 2216: 0021 db byte, 33 2218: E8 db lt 2219: 300B db bra_ifnot,vt11-$ 221B: 9B213333 221F: 3C333300 2223: C2 db string, "!33<33",0, print 2224: 2224: 002C vt11 db byte, 44 2226: 0021 db byte, 33 2228: E8 db lt 2229: 300B db bra_ifnot,vt12-$ 222B: 9B213434 222F: 3C333300 2233: C2 db string, "!44<33",0, print 2234: 2234: 002100D4 2238: E6 vt12 db byte, 33, byte, -44, ge 2239: 2D0D db bra_if,vt13-$ 223B: 9B213333 223F: 3E3D2D34 2243: 3400C2 db string, "!33>=-44",0, print 2246: 2246: 00D40021 224A: E6 vt13 db byte, -44, byte, 33, ge 224B: 300D db bra_ifnot,vt14-$ 224D: 9B212D34 2251: 343E3D33 2255: 3300C2 db string, "!-44>=33",0, print 2258: 2258: 00FF0000 225C: E6 vt14 db byte, -1, byte, 0, ge 225D: 300B db bra_ifnot,vt15-$ 225F: 9B212D31 2263: 3E3D3000 2267: C2 db string, "!-1>=0",0, print 2268: 2268: 03008003 226C: FF7FE6 vt15 db number, $00,$80, number, $ff,$7f, ge 226F: 3010 db bra_ifnot,vt16-$ 2271: 9B212D6D 2275: 61783E3D 2279: 2B6D6178 227D: 00C2 db string, "!-max>=+max",0, print 227F: 227F: 03008003 2283: FF7FE4 vt16 db number, $00,$80, number, $ff,$7f, gt 2286: 300F db bra_ifnot,vt17-$ 2288: 9B212D6D 228C: 61783E2B 2290: 6D617800 2294: C2 db string, "!-max>+max",0, print 2295: 2295: 0021002C 2299: 0903 vt17 db byte, 33, byte, 44, mult, number 229B: AC05 dw 33*44 229D: E0 db eq 229E: 2D12 db bra_if,vt18-$ 22A0: 9B213333 22A4: 2A34343D 22A8: 00C2 db string, "!33*44=",0, print 22AA: 0021002C 22AE: 09C8 db byte, 33, byte, 44, mult, printdec 22B0: 22B0: 00DF002C 22B4: 0903 vt18 db byte, -33, byte, 44, mult, number 22B6: 54FA dw -33*44 22B8: E0 db eq 22B9: 2D13 db bra_if,vt19-$ 22BB: 9B212D33 22BF: 332A3434 22C3: 3D00C2 db string, "!-33*44=",0, print 22C6: 00DF002C 22CA: 09C8 db byte, -33, byte, 44, mult, printdec 22CC: 22CC: 002100D4 22D0: 0903 vt19 db byte, 33, byte, -44, mult, number 22D2: 54FA dw -33*44 22D4: E0 db eq 22D5: 2D13 db bra_if,vt20-$ 22D7: 9B213333 22DB: 2A2D3434 22DF: 3D00C2 db string, "!33*-44=",0, print 22E2: 002100D4 22E6: 09C8 db byte, 33, byte, -44, mult, printdec 22E8: 22E8: 0000002C 22EC: 090000E0 vt20 db byte, 0, byte, 44, mult, byte, 0, eq 22F0: 2D11 db bra_if,vt21-$ 22F2: 9B21302A 22F6: 34343D00 22FA: C2 db string, "!0*44=",0, print 22FB: 0000002C 22FF: 09C8 db byte, 0, byte, 44, mult, printdec 2301: 2301: 00DF0000 2305: 090000E0 vt21 db byte, -33, byte, 0, mult, byte, 0, eq 2309: 2D12 db bra_if,vt22-$ 230B: 9B212D33 230F: 332A303D 2313: 00C2 db string, "!-33*0=",0, print 2315: 00DF0000 2319: 09C8 db byte, -33, byte, 0, mult, printdec 231B: 231B: 03 vt22 db number 231C: 4D01 dw 333 231E: 00D40903 db byte, -44, mult, number 2322: C4C6 dw 333*-44 2324: E0 db eq 2325: 2D15 db bra_if,vt23-$ 2327: 9B213333 232B: 332A2D34 232F: 343D00C2 db string, "!333*-44=",0, print 2333: 03 db number 2334: 4D01 dw 333 2336: 00D409C8 db byte, -44, mult, printdec 233A: 233A: 00DF00D4 233E: 0903 vt23 db byte, -33, byte, -44, mult, number 2340: AC05 dw 33*44 2342: E0 db eq 2343: 2D14 db bra_if,vt25-$ 2345: 9B212D33 2349: 332A2D34 234D: 343D00C2 db string, "!-33*-44=",0, print 2351: 00DF00D4 2355: 09C8 db byte, -33, byte, -44, mult, printdec 2357: 2357: 00050004 235B: 920004E0 vt25 db byte, 5, byte, 4, min, byte, 4, eq 235F: 2D0E db bra_if,vt26-$ 2361: 9B216D69 2365: 6E28352C 2369: 342900C2 db string, "!min(5,4)",0, print 236D: 236D: 00FB00FC 2371: 9200FBE0 vt26 db byte, -5, byte, -4, min, byte, -5, eq 2375: 2D10 db bra_if,vt27-$ 2377: 9B216D69 237B: 6E282D35 237F: 2C2D3429 2383: 00C2 db string, "!min(-5,-4)",0, print 2385: 2385: 00FB0004 2389: 9200FBE0 vt27 db byte, -5, byte, 4, min, byte, -5, eq 238D: 2D0F db bra_if,vt28-$ 238F: 9B216D69 2393: 6E282D35 2397: 2C342900 239B: C2 db string, "!min(-5,4)",0, print 239C: 239C: 000500FC 23A0: 9200FCE0 vt28 db byte, 5, byte, -4, min, byte, -4, eq 23A4: 2D0F db bra_if,vt29-$ 23A6: 9B216D69 23AA: 6E28352C 23AE: 2D342900 23B2: C2 db string, "!min(5,-4)",0, print 23B3: 23B3: vt29 23B3: 23B3: 9B20646F 23B7: 6E652E00 23BB: C2 db string," done.",0,print 23BC: 69 db to_real 23BD: C9 ret 23BE: 23BE: 23BE: 23BE: 23BE: 23BE: 23BE: 23BE: 23BE: #include "vip test.ass" 23BE: 23BE: 23BE: sys_info_attr equ cyan_paper+black+bright 23BE: sys_info_h_attr equ green_paper+white 23BE: 23BE: 23BE: ; ---------------------------------------------- 23BE: ; System-Info anzeigen 23BE: ; 23BE: ; Verzweigt danach wieder zum Hauptmenu 23BE: ; 23BE: ; in: -- 23BE: ; out: does not return 23BE: ; mod: does not return 23BE: 23BE: system_info: 23BE: 23BE: E7 rst vip 23BF: 23BF: ; "Software Info" 23BF: 23BF: 9B066802 db string, ctl_setattr,sys_info_attr,ctl_cls 23C3: 0627 db ctl_setattr,sys_info_h_attr 23C5: 03012053 23C9: 6F667477 23CD: 61726520 23D1: 496E666F db ctl_locate,1,32, "Software Info" 23D5: 06680D db ctl_setattr,sys_info_attr,$0d 23D8: 23D8: ; "IC Tester Version" 23D8: 23D8: 0D494320 23DC: 54657374 23E0: 65722076 23E4: 65727369 23E8: 6F6E3A0A 23EC: 302E31 db $0d,"IC Tester version:", ctl_tab, "0.1" 23EF: 0D4C6173 23F3: 74206D6F 23F7: 64696669 23FB: 65643A0A 23FF: 0A332E4F 2403: 63742E32 2407: 303036 db $0d,"Last modified:", ctl_tab,ctl_tab, __date__ 240A: 240A: ; "Mem pack size" 240A: 240A: 0D4D656D 240E: 6F727920 2412: 7061636B 2416: 2073697A 241A: 653A0480 241E: 00 db $0d,"Memory pack size:", ctl_setcol,128,0 241F: C2 db print 2420: 03 db number 2421: FB03 dw mempack_end-mempack_start 2423: C8 db printdec 2424: 2424: ; "Scr pack size" 2424: 2424: 9B0D5363 2428: 7265656E 242C: 20706163 2430: 6B207369 2434: 7A653A04 2438: 8000C2 db string, $0d,"Screen pack size:", ctl_setcol,128,$00, print 243B: 03 db number 243C: FE02 dw screen_end-screen_start 243E: C8 db printdec 243F: 243F: ; "Text pack size" 243F: 243F: 9B0D5465 2443: 78742070 2447: 61636B20 244B: 73697A65 244F: 3A048000 2453: C2 db string, $0d,"Text pack size:", ctl_setcol,128,$00, print 2454: 03 db number 2455: B107 dw print_end-print_start 2457: C8 db printdec 2458: 2458: ; "Virtual machine size" 2458: 2458: 9B0D5669 245C: 72747561 2460: 6C206D61 2464: 6368696E 2468: 65207369 246C: 7A653A04 2470: 8000C2 db string, $0d,"Virtual machine size:", ctl_setcol, 128, 0, print 2473: 03 db number 2474: DA05 dw vip_end-vip_start 2476: C8 db printdec 2477: 9B202874 247B: 61626C65 247F: 3A2000C2 db string, " (table: ",0, print 2483: 03 db number 2484: F700 dw v_tab_end-v_tab 2486: C8 db printdec 2487: 9B2900C2 db string, ")",0, print 248B: 248B: ; "Hardware Info" 248B: 248B: 9B0D0D06 248F: 27 db string, $0d,$0d,ctl_setattr,sys_info_h_attr 2490: 04204861 2494: 72647761 2498: 72652049 249C: 6E666F db ctl_setcol,32, "Hardware Info" 249F: 06680D00 db ctl_setattr,sys_info_attr,$0d,0 24A3: C2 db print 24A4: 24A4: ; "Total Ram Size" 24A4: 24A4: 9B0D546F 24A8: 74616C20 24AC: 52414D20 24B0: 73697A65 24B4: 3A048024 24B8: 00C2 db string, $0d, "Total RAM size:", ctl_setcol,128,'$',0, print 24BA: 03005B12 db number, RAMTOP%256, RAMTOP/256, peek 24BE: 030040DE db number, $00, $40, sub 24C2: 6BCB db dup, printhex 24C4: 9B202800 24C8: C2 db string, " (",0, print 24C9: C8 db printdec 24CA: 9B2900C2 db string, ")",0, print 24CE: 24CE: ; "Ram Bytes Free" 24CE: 24CE: 9B0D5241 24D2: 4D206279 24D6: 74657320 24DA: 66726565 24DE: 3A048000 24E2: C2 db string, $0d,"RAM bytes free:", ctl_setcol,128,$00, print 24E3: 36 db opcode 24E4: BA10 dw v_mem_get_free_total 24E6: C8 db printdec 24E7: 24E7: ; "Rom Bytes Free" 24E7: 24E7: 9B0D524F 24EB: 4D206279 24EF: 74657320 24F3: 756E7573 24F7: 65643A0A 24FB: 00C2 db string, $0d,"ROM bytes unused:", ctl_tab,0, print 24FD: 03004003 2501: DB27DE db number, $00, $40, number, code_end%256, code_end/256, sub 2504: C8 db printdec 2505: 2505: ; "Min. Stack Free" 2505: 2505: 9B0D4D69 2509: 6E2E2073 250D: 7461636B 2511: 20667265 2515: 653A0480 2519: 00C2 db string, $0d,"Min. stack free:", ctl_setcol,128,0, print 251B: 36 db opcode 251C: 3C25 dw v_calc_min_stack_free 251E: C8 db printdec 251F: 69 db to_real 2520: 2520: 2520: ; "Press Any Key" 2520: 2520: CD2625 call press_any_key 2523: C3BE00 jp main_menu 2526: 2526: 2526: 2526: ; --------------------------------------------- 2526: ; Display "Press any key" 2526: ; and wait for key and flush key 2526: ; 2526: ; in: -- 2526: ; out: -- 2526: ; mod: af 2526: 2526: press_any_key: 2526: CF rst print_msg 2527: 0D0D0422 252B: 0617 defb $0d,$0d,ctl_setcol,34,ctl_setattr,red_paper+white 252D: 5B707265 2531: 7373206B 2535: 65795D00 defm "[press key]",$00 2539: C35B1B jp wait_newkey 253C: 253C: 253C: 253C: 253C: ; --------------------------------------- 253C: ; Ermittle das bisher aufgetretene Stack-Free-Minimum 253C: ; Ann.: Der Stack schließt sich direkt an das dynamisch verwaltete freie RAM an. 253C: ; Jemals verwendete Bytes auf dem Stack werden an ihrem Wert != 0 erkannt. 253C: 253C: v_calc_min_stack_free ; opcode v_calc_min_stack_free -- 253C: D5 push de 253D: 253D: 2A255B ld hl,(mem_end) 2540: 5D54 ld de,hl 2542: AF xor a 2543: 2B dec hl 2544: 2544: 23 cms1 inc hl ; suche das erste byte != 0 2545: B6 or (hl) 2546: 28FC jr z,cms1 2548: 2548: ED52 sbc hl,de 254A: 254A: EB ex hl,de 254B: FDE9 jp (iy) 254D: 254D: 254D: 254D: #include "sysinfo.ass" 254D: 254D: print_obit_menu: 254D: CF rst print_msg 254E: 010510 db ctl_home,ctl_setrow,16 2551: 0668 db ctl_setattr,cyan_paper+black+bright 2553: 00 db 0 2554: 2554: 210050 ld hl,$5000 ; Zeile 16 2557: 011008 ld bc,256*8 + 16 ; rows, char_cols 255A: 3E68 ld a,cyan_paper+black+bright 255C: CD9B0C call clear_cbox_with_attr 255F: 255F: CF rst print_msg 2560: 28542904 2564: 18546F67 2568: 676C6520 256C: 70696E db "(T)", ctl_setcol,24, "Toggle pin" 256F: ;db $0d, "(F)", ctl_setcol,24, "Trigger pin" 256F: 0D283129 2573: 04185365 2577: 74207069 257B: 6E20746F 257F: 20273127 db $0d, "(1)", ctl_setcol,24, "Set pin to '1'" 2583: 0D283029 2587: 04185365 258B: 74207069 258F: 6E20746F 2593: 20273027 db $0d, "(0)", ctl_setcol,24, "Set pin to '0'" 2597: 00 db 0 2598: C9 ret 2599: 2599: print_type_menu: 2599: CF rst print_msg 259A: 010510 db ctl_home,ctl_setrow,16 259D: 0668 db ctl_setattr,cyan_paper+black+bright 259F: 00 db 0 25A0: 25A0: 210050 ld hl,$5000 ; Zeile 16 25A3: 011008 ld bc,256*8 + 16 ; rows, char_cols 25A6: 3E68 ld a,cyan_paper+black+bright 25A8: CD9B0C call clear_cbox_with_attr 25AB: 25AB: CF rst print_msg 25AC: 28492904 25B0: 18496E70 25B4: 7574 db "(I)", ctl_setcol,24, "Input" 25B6: 0D284F29 25BA: 04184F75 25BE: 74707574 db $0d, "(O)", ctl_setcol,24, "Output" 25C2: 0D283329 25C6: 04183373 25CA: 74617465 25CE: 206F7574 25D2: 707574 db $0d, "(3)", ctl_setcol,24, "3state output" 25D5: 0D284B29 25D9: 04186F2E 25DD: 4B2E206F 25E1: 75747075 25E5: 74 db $0d, "(K)", ctl_setcol,24, "o.K. output" 25E6: 0D285829 25EA: 0418492F 25EE: 4F db $0d, "(X)", ctl_setcol,24, "I/O" 25EF: 0D284E29 25F3: 04186E2E 25F7: 632E db $0d, "(N)", ctl_setcol,24, "n.c." 25F9: 0D285629 25FD: 04185663 2601: 63 db $0d, "(V)", ctl_setcol,24, "Vcc" ; zufällig selbe Taste wie '+': Vcc on 2602: 0D284729 2606: 0418474E 260A: 44 db $0d, "(G)", ctl_setcol,24, "GND" ; zufällig selbe Taste wie '-': Vcc off 260B: ; db $0d, "(U)", ctl_setcol,24, "unknown" 260B: 00 db 0 260C: C9 ret 260D: 260D: print_name_menu: 260D: CF rst print_msg 260E: 010510 db ctl_home,ctl_setrow,16 2611: 0668 db ctl_setattr,cyan_paper+black+bright 2613: 00 db 0 2614: 2614: 210050 ld hl,$5000 ; Zeile 16 2617: 011008 ld bc,256*8 + 16 ; rows, char_cols 261A: 3E68 ld a,cyan_paper+black+bright 261C: CD9B0C call clear_cbox_with_attr 261F: 261F: CF rst print_msg 2620: 5B454E54 2624: 45525D20 2628: 746F2065 262C: 64697420 2630: 6E616D65 db "[ENTER] to edit name" 2634: 0D652E67 2638: 2E3A db $0d, "e.g.:" 263A: 0D202041 263E: 78782061 2642: 64647265 2646: 7373 db $0d, " Axx address" 2648: 0D202044 264C: 78782064 2650: 617461 db $0d, " Dxx data" 2653: 0D202056 2657: 63632073 265B: 7570706C 265F: 79 db $0d, " Vcc supply" 2660: 0D202047 2664: 4E442067 2668: 726F756E 266C: 64 db $0d, " GND ground" 266D: 0D20202F 2671: 43452C20 2675: 2F57452C 2679: 202F5244 db $0d, " /CE, /WE, /RD" 267D: 00 db 0 267E: C9 ret 267F: 267F: 267F: free_test_menu: 267F: CF rst print_msg 2680: 066802 db ctl_setattr,cyan_paper+black+bright,ctl_cls 2683: 0627 db ctl_setattr,green_paper+white 2685: 0D204672 2689: 65652054 268D: 65737420 2691: 0D db $0d, " Free Test ", $0d 2692: 0668 db ctl_setattr,cyan_paper+black+bright 2694: 2694: 0D285129 2698: 04184578 269C: 6974 db $0d,"(Q)", ctl_setcol,24, "Exit" 269E: 0D db $0d 269F: 0D285A29 26A3: 04185365 26A7: 74207069 26AB: 6E20636F 26AF: 756E74 db $0d,"(Z)", ctl_setcol,24, "Set pin count" 26B2: 0D284529 26B6: 04184564 26BA: 69742049 26BE: 4320696E 26C2: 666F db $0d,"(E)", ctl_setcol,24, "Edit IC info" 26C4: 0D285229 26C8: 04184665 26CC: 74636820 26D0: 49432069 26D4: 6E666F db $0d,"(R)", ctl_setcol,24, "Fetch IC info" 26D7: 0D285729 26DB: 04185374 26DF: 6F726520 26E3: 49432069 26E7: 6E666F db $0d,"(W)", ctl_setcol,24, "Store IC info" 26EA: 0D285029 26EE: 04184361 26F2: 6C632E20 26F6: 63686563 26FA: 6B73756D db $0d,"(P)", ctl_setcol,24, "Calc. checksum" 26FE: 0D db $0d 26FF: 0D282B29 2703: 04185377 2707: 69746368 270B: 20566363 270F: 204F4E db $0d,"(+)", ctl_setcol,24, "Switch Vcc ON" ; or 'J' 2712: 0D282D29 2716: 04185377 271A: 69746368 271E: 20566363 2722: 204F4646 db $0d,"(-)", ctl_setcol,24, "Switch Vcc OFF" ; or 'K' 2726: 0D9C9D db $0d, charcode_left_arrow,charcode_down_arrow 2729: 9E9F db charcode_up_arrow, charcode_right_arrow 272B: 206D6F76 272F: 65206172 2733: 6F756E64 db " move around" 2737: 00 db 0 2738: 2738: 2738: CD251E call start_pin_display 273B: CD581C call ic_draw_all_pin_types 273E: ED4BA35C ld bc,(ic_hilight_row_col) ; b=row, c=col 2742: CD601D call ic_set_hilight 2745: 2745: 2745: 2745: ED4BA35C ft1 ld bc,(ic_hilight_row_col) ; b=row, c=col 2749: CD311D call test_col_c_is_obit ; z = ja 274C: CC4D25 call z,print_obit_menu 274F: CD381D call test_col_c_is_name ; z = ja 2752: CC0D26 call z,print_name_menu 2755: CD3F1D call test_col_c_is_type ; z = ja 2758: CC9925 call z,print_type_menu 275B: 275B: ED7B005B ld sp,(RAMTOP) 275F: CDE518 call print_error_message ; falls vorhanden 2762: 2762: CDA200 call inkey_dispatcher 2765: 2765: ; allways present keys: 2765: 71 defb 'q' 2766: BE00 defw main_menu 2768: 7A defb 'z' 2769: DA27 defw set_pin_count 276B: 65 defb 'e' 276C: DA27 defw edit_pin_info 276E: 72 defb 'r' 276F: DA27 defw fetch_ic_info 2771: 77 defb 'w' 2772: DA27 defw store_ic_info 2774: 70 defb 'p' 2775: DA27 defw calc_checksum 2777: 2B defb '+' 2778: 691F defw ic_switch_vcc_on 277A: 4B defb 'K' ; selbe Taste nur mit caps shift 277B: 691F defw ic_switch_vcc_on 277D: 2D defb '-' 277E: 711F defw ic_switch_vcc_off 2780: 4A defb 'J' ; selbe Taste nur mit caps shift 2781: 711F defw ic_switch_vcc_off 2783: 2783: ; obit menu: 2783: 74 defb 't' 2784: 901E defw ic_toggle_current_pin 2786: 66 defb 'f' 2787: 9E1E defw ic_trigger_current_pin 2789: 31 defb '1' 278A: 821E defw ic_set_current_pin 278C: 30 defb '0' 278D: 701E defw ic_reset_current_pin 278F: 278F: ; type menu: 278F: 69 defb 'i' 2790: B227 defw set_pintype_input 2792: 6F defb 'o' 2793: B627 defw set_pintype_output 2795: 33 defb '3' 2796: BA27 defw set_pintype_3state 2798: 6B defb 'k' 2799: BE27 defw set_pintype_oK 279B: 78 defb 'x' 279C: C227 defw set_pintype_io 279E: 6E defb 'n' 279F: C627 defw set_pintype_nc 27A1: 76 defb 'v' 27A2: CA27 defw set_pintype_vcc 27A4: 67 defb 'g' 27A5: CE27 defw set_pintype_gnd 27A7: 75 defb 'u' 27A8: D227 defw set_pintype_unknown 27AA: 27AA: ; name menu: 27AA: 0D defb 13 27AB: DA27 defw edit_pin_name 27AD: 27AD: 27AD: 00 defb 0 27AE: E31D defw ic_move_hilight ; handle cursor key or ignore invalid key 27B0: 27B0: 1893 jr ft1 27B2: 27B2: 27B2: 27B2: 27B2: 27B2: set_pintype_input 27B2: 3E03 ld a,ic_pin_type_input 27B4: 181E jr spt1 27B6: set_pintype_output 27B6: 3E04 ld a,ic_pin_type_output 27B8: 181A jr spt1 27BA: set_pintype_3state 27BA: 3E07 ld a,ic_pin_type_3state 27BC: 1816 jr spt1 27BE: set_pintype_oK 27BE: 3E06 ld a,ic_pin_type_oK 27C0: 1812 jr spt1 27C2: set_pintype_io 27C2: 3E05 ld a,ic_pin_type_io 27C4: 180E jr spt1 27C6: set_pintype_nc 27C6: 3E08 ld a,ic_pin_type_nc 27C8: 180A jr spt1 27CA: set_pintype_vcc 27CA: 3E02 ld a,ic_pin_type_vcc 27CC: 1806 jr spt1 27CE: set_pintype_gnd 27CE: 3E01 ld a,ic_pin_type_gnd 27D0: 1802 jr spt1 27D2: set_pintype_unknown 27D2: 3E00 ld a,ic_pin_type_unknown 27D4: ;jr spt1 27D4: CD4C1C spt1 call ic_set_pin_type_for_current_pin 27D7: C3E11D jp ic_move_hilight_down 27DA: 27DA: edit_pin_name 27DA: set_pin_count 27DA: edit_pin_info 27DA: fetch_ic_info 27DA: store_ic_info 27DA: calc_checksum 27DA: 27DA: C9 ret ; NIMP 27DB: 27DB: #include "free test.ass" 27DB: 27DB: 27DB: 27DB: 27DB: FFFFFFFF 27DF: FFFFFFFF 27E3: FFFFFFFF 27E7: FFFFFFFF 27EB: FFFFFFFF 27EF: FFFFFFFF 27F3: FFFFFFFF 27F7: FFFFFFFF 27FB: FFFFFFFF 27FF: FFFFFFFF 2803: FFFFFFFF 2807: FFFFFFFF 280B: FFFFFFFF 280F: FFFFFFFF 2813: FFFFFFFF 2817: FFFFFFFF 281B: FFFFFFFF 281F: FFFFFFFF 2823: FFFFFFFF 2827: FFFFFFFF 282B: FFFFFFFF 282F: FFFFFFFF 2833: FFFFFFFF 2837: FFFFFFFF 283B: FFFFFFFF 283F: FFFFFFFF 2843: FFFFFFFF 2847: FFFFFFFF 284B: FFFFFFFF 284F: FFFFFFFF 2853: FFFFFFFF 2857: FFFFFFFF 285B: FFFFFFFF 285F: FFFFFFFF 2863: FFFFFFFF 2867: FFFFFFFF 286B: FFFFFFFF 286F: FFFFFFFF 2873: FFFFFFFF 2877: FFFFFFFF 287B: FFFFFFFF 287F: FFFFFFFF 2883: FFFFFFFF 2887: FFFFFFFF 288B: FFFFFFFF 288F: FFFFFFFF 2893: FFFFFFFF 2897: FFFFFFFF 289B: FFFFFFFF 289F: FFFFFFFF 28A3: FFFFFFFF 28A7: FFFFFFFF 28AB: FFFFFFFF 28AF: FFFFFFFF 28B3: FFFFFFFF 28B7: FFFFFFFF 28BB: FFFFFFFF 28BF: FFFFFFFF 28C3: FFFFFFFF 28C7: FFFFFFFF 28CB: FFFFFFFF 28CF: FFFFFFFF 28D3: FFFFFFFF 28D7: FFFFFFFF 28DB: FFFFFFFF 28DF: FFFFFFFF 28E3: FFFFFFFF 28E7: FFFFFFFF 28EB: FFFFFFFF 28EF: FFFFFFFF 28F3: FFFFFFFF 28F7: FFFFFFFF 28FB: FFFFFFFF 28FF: FFFFFFFF 2903: FFFFFFFF 2907: FFFFFFFF 290B: FFFFFFFF 290F: FFFFFFFF 2913: FFFFFFFF 2917: FFFFFFFF 291B: FFFFFFFF 291F: FFFFFFFF 2923: FFFFFFFF 2927: FFFFFFFF 292B: FFFFFFFF 292F: FFFFFFFF 2933: FFFFFFFF 2937: FFFFFFFF 293B: FFFFFFFF 293F: FFFFFFFF 2943: FFFFFFFF 2947: FFFFFFFF 294B: FFFFFFFF 294F: FFFFFFFF 2953: FFFFFFFF 2957: FFFFFFFF 295B: FFFFFFFF 295F: FFFFFFFF 2963: FFFFFFFF 2967: FFFFFFFF 296B: FFFFFFFF 296F: FFFFFFFF 2973: FFFFFFFF 2977: FFFFFFFF 297B: FFFFFFFF 297F: FFFFFFFF 2983: FFFFFFFF 2987: FFFFFFFF 298B: FFFFFFFF 298F: FFFFFFFF 2993: FFFFFFFF 2997: FFFFFFFF 299B: FFFFFFFF 299F: FFFFFFFF 29A3: FFFFFFFF 29A7: FFFFFFFF 29AB: FFFFFFFF 29AF: FFFFFFFF 29B3: FFFFFFFF 29B7: FFFFFFFF 29BB: FFFFFFFF 29BF: FFFFFFFF 29C3: FFFFFFFF 29C7: FFFFFFFF 29CB: FFFFFFFF 29CF: FFFFFFFF 29D3: FFFFFFFF 29D7: FFFFFFFF 29DB: FFFFFFFF 29DF: FFFFFFFF 29E3: FFFFFFFF 29E7: FFFFFFFF 29EB: FFFFFFFF 29EF: FFFFFFFF 29F3: FFFFFFFF 29F7: FFFFFFFF 29FB: FFFFFFFF 29FF: FFFFFFFF 2A03: FFFFFFFF 2A07: FFFFFFFF 2A0B: FFFFFFFF 2A0F: FFFFFFFF 2A13: FFFFFFFF 2A17: FFFFFFFF 2A1B: FFFFFFFF 2A1F: FFFFFFFF 2A23: FFFFFFFF 2A27: FFFFFFFF 2A2B: FFFFFFFF 2A2F: FFFFFFFF 2A33: FFFFFFFF 2A37: FFFFFFFF 2A3B: FFFFFFFF 2A3F: FFFFFFFF 2A43: FFFFFFFF 2A47: FFFFFFFF 2A4B: FFFFFFFF 2A4F: FFFFFFFF 2A53: FFFFFFFF 2A57: FFFFFFFF 2A5B: FFFFFFFF 2A5F: FFFFFFFF 2A63: FFFFFFFF 2A67: FFFFFFFF 2A6B: FFFFFFFF 2A6F: FFFFFFFF 2A73: FFFFFFFF 2A77: FFFFFFFF 2A7B: FFFFFFFF 2A7F: FFFFFFFF 2A83: FFFFFFFF 2A87: FFFFFFFF 2A8B: FFFFFFFF 2A8F: FFFFFFFF 2A93: FFFFFFFF 2A97: FFFFFFFF 2A9B: FFFFFFFF 2A9F: FFFFFFFF 2AA3: FFFFFFFF 2AA7: FFFFFFFF 2AAB: FFFFFFFF 2AAF: FFFFFFFF 2AB3: FFFFFFFF 2AB7: FFFFFFFF 2ABB: FFFFFFFF 2ABF: FFFFFFFF 2AC3: FFFFFFFF 2AC7: FFFFFFFF 2ACB: FFFFFFFF 2ACF: FFFFFFFF 2AD3: FFFFFFFF 2AD7: FFFFFFFF 2ADB: FFFFFFFF 2ADF: FFFFFFFF 2AE3: FFFFFFFF 2AE7: FFFFFFFF 2AEB: FFFFFFFF 2AEF: FFFFFFFF 2AF3: FFFFFFFF 2AF7: FFFFFFFF 2AFB: FFFFFFFF 2AFF: FFFFFFFF 2B03: FFFFFFFF 2B07: FFFFFFFF 2B0B: FFFFFFFF 2B0F: FFFFFFFF 2B13: FFFFFFFF 2B17: FFFFFFFF 2B1B: FFFFFFFF 2B1F: FFFFFFFF 2B23: FFFFFFFF 2B27: FFFFFFFF 2B2B: FFFFFFFF 2B2F: FFFFFFFF 2B33: FFFFFFFF 2B37: FFFFFFFF 2B3B: FFFFFFFF 2B3F: FFFFFFFF 2B43: FFFFFFFF 2B47: FFFFFFFF 2B4B: FFFFFFFF 2B4F: FFFFFFFF 2B53: FFFFFFFF 2B57: FFFFFFFF 2B5B: FFFFFFFF 2B5F: FFFFFFFF 2B63: FFFFFFFF 2B67: FFFFFFFF 2B6B: FFFFFFFF 2B6F: FFFFFFFF 2B73: FFFFFFFF 2B77: FFFFFFFF 2B7B: FFFFFFFF 2B7F: FFFFFFFF 2B83: FFFFFFFF 2B87: FFFFFFFF 2B8B: FFFFFFFF 2B8F: FFFFFFFF 2B93: FFFFFFFF 2B97: FFFFFFFF 2B9B: FFFFFFFF 2B9F: FFFFFFFF 2BA3: FFFFFFFF 2BA7: FFFFFFFF 2BAB: FFFFFFFF 2BAF: FFFFFFFF 2BB3: FFFFFFFF 2BB7: FFFFFFFF 2BBB: FFFFFFFF 2BBF: FFFFFFFF 2BC3: FFFFFFFF 2BC7: FFFFFFFF 2BCB: FFFFFFFF 2BCF: FFFFFFFF 2BD3: FFFFFFFF 2BD7: FFFFFFFF 2BDB: FFFFFFFF 2BDF: FFFFFFFF 2BE3: FFFFFFFF 2BE7: FFFFFFFF 2BEB: FFFFFFFF 2BEF: FFFFFFFF 2BF3: FFFFFFFF 2BF7: FFFFFFFF 2BFB: FFFFFFFF 2BFF: FFFFFFFF 2C03: FFFFFFFF 2C07: FFFFFFFF 2C0B: FFFFFFFF 2C0F: FFFFFFFF 2C13: FFFFFFFF 2C17: FFFFFFFF 2C1B: FFFFFFFF 2C1F: FFFFFFFF 2C23: FFFFFFFF 2C27: FFFFFFFF 2C2B: FFFFFFFF 2C2F: FFFFFFFF 2C33: FFFFFFFF 2C37: FFFFFFFF 2C3B: FFFFFFFF 2C3F: FFFFFFFF 2C43: FFFFFFFF 2C47: FFFFFFFF 2C4B: FFFFFFFF 2C4F: FFFFFFFF 2C53: FFFFFFFF 2C57: FFFFFFFF 2C5B: FFFFFFFF 2C5F: FFFFFFFF 2C63: FFFFFFFF 2C67: FFFFFFFF 2C6B: FFFFFFFF 2C6F: FFFFFFFF 2C73: FFFFFFFF 2C77: FFFFFFFF 2C7B: FFFFFFFF 2C7F: FFFFFFFF 2C83: FFFFFFFF 2C87: FFFFFFFF 2C8B: FFFFFFFF 2C8F: FFFFFFFF 2C93: FFFFFFFF 2C97: FFFFFFFF 2C9B: FFFFFFFF 2C9F: FFFFFFFF 2CA3: FFFFFFFF 2CA7: FFFFFFFF 2CAB: FFFFFFFF 2CAF: FFFFFFFF 2CB3: FFFFFFFF 2CB7: FFFFFFFF 2CBB: FFFFFFFF 2CBF: FFFFFFFF 2CC3: FFFFFFFF 2CC7: FFFFFFFF 2CCB: FFFFFFFF 2CCF: FFFFFFFF 2CD3: FFFFFFFF 2CD7: FFFFFFFF 2CDB: FFFFFFFF 2CDF: FFFFFFFF 2CE3: FFFFFFFF 2CE7: FFFFFFFF 2CEB: FFFFFFFF 2CEF: FFFFFFFF 2CF3: FFFFFFFF 2CF7: FFFFFFFF 2CFB: FFFFFFFF 2CFF: FFFFFFFF 2D03: FFFFFFFF 2D07: FFFFFFFF 2D0B: FFFFFFFF 2D0F: FFFFFFFF 2D13: FFFFFFFF 2D17: FFFFFFFF 2D1B: FFFFFFFF 2D1F: FFFFFFFF 2D23: FFFFFFFF 2D27: FFFFFFFF 2D2B: FFFFFFFF 2D2F: FFFFFFFF 2D33: FFFFFFFF 2D37: FFFFFFFF 2D3B: FFFFFFFF 2D3F: FFFFFFFF 2D43: FFFFFFFF 2D47: FFFFFFFF 2D4B: FFFFFFFF 2D4F: FFFFFFFF 2D53: FFFFFFFF 2D57: FFFFFFFF 2D5B: FFFFFFFF 2D5F: FFFFFFFF 2D63: FFFFFFFF 2D67: FFFFFFFF 2D6B: FFFFFFFF 2D6F: FFFFFFFF 2D73: FFFFFFFF 2D77: FFFFFFFF 2D7B: FFFFFFFF 2D7F: FFFFFFFF 2D83: FFFFFFFF 2D87: FFFFFFFF 2D8B: FFFFFFFF 2D8F: FFFFFFFF 2D93: FFFFFFFF 2D97: FFFFFFFF 2D9B: FFFFFFFF 2D9F: FFFFFFFF 2DA3: FFFFFFFF 2DA7: FFFFFFFF 2DAB: FFFFFFFF 2DAF: FFFFFFFF 2DB3: FFFFFFFF 2DB7: FFFFFFFF 2DBB: FFFFFFFF 2DBF: FFFFFFFF 2DC3: FFFFFFFF 2DC7: FFFFFFFF 2DCB: FFFFFFFF 2DCF: FFFFFFFF 2DD3: FFFFFFFF 2DD7: FFFFFFFF 2DDB: FFFFFFFF 2DDF: FFFFFFFF 2DE3: FFFFFFFF 2DE7: FFFFFFFF 2DEB: FFFFFFFF 2DEF: FFFFFFFF 2DF3: FFFFFFFF 2DF7: FFFFFFFF 2DFB: FFFFFFFF 2DFF: FFFFFFFF 2E03: FFFFFFFF 2E07: FFFFFFFF 2E0B: FFFFFFFF 2E0F: FFFFFFFF 2E13: FFFFFFFF 2E17: FFFFFFFF 2E1B: FFFFFFFF 2E1F: FFFFFFFF 2E23: FFFFFFFF 2E27: FFFFFFFF 2E2B: FFFFFFFF 2E2F: FFFFFFFF 2E33: FFFFFFFF 2E37: FFFFFFFF 2E3B: FFFFFFFF 2E3F: FFFFFFFF 2E43: FFFFFFFF 2E47: FFFFFFFF 2E4B: FFFFFFFF 2E4F: FFFFFFFF 2E53: FFFFFFFF 2E57: FFFFFFFF 2E5B: FFFFFFFF 2E5F: FFFFFFFF 2E63: FFFFFFFF 2E67: FFFFFFFF 2E6B: FFFFFFFF 2E6F: FFFFFFFF 2E73: FFFFFFFF 2E77: FFFFFFFF 2E7B: FFFFFFFF 2E7F: FFFFFFFF 2E83: FFFFFFFF 2E87: FFFFFFFF 2E8B: FFFFFFFF 2E8F: FFFFFFFF 2E93: FFFFFFFF 2E97: FFFFFFFF 2E9B: FFFFFFFF 2E9F: FFFFFFFF 2EA3: FFFFFFFF 2EA7: FFFFFFFF 2EAB: FFFFFFFF 2EAF: FFFFFFFF 2EB3: FFFFFFFF 2EB7: FFFFFFFF 2EBB: FFFFFFFF 2EBF: FFFFFFFF 2EC3: FFFFFFFF 2EC7: FFFFFFFF 2ECB: FFFFFFFF 2ECF: FFFFFFFF 2ED3: FFFFFFFF 2ED7: FFFFFFFF 2EDB: FFFFFFFF 2EDF: FFFFFFFF 2EE3: FFFFFFFF 2EE7: FFFFFFFF 2EEB: FFFFFFFF 2EEF: FFFFFFFF 2EF3: FFFFFFFF 2EF7: FFFFFFFF 2EFB: FFFFFFFF 2EFF: FFFFFFFF 2F03: FFFFFFFF 2F07: FFFFFFFF 2F0B: FFFFFFFF 2F0F: FFFFFFFF 2F13: FFFFFFFF 2F17: FFFFFFFF 2F1B: FFFFFFFF 2F1F: FFFFFFFF 2F23: FFFFFFFF 2F27: FFFFFFFF 2F2B: FFFFFFFF 2F2F: FFFFFFFF 2F33: FFFFFFFF 2F37: FFFFFFFF 2F3B: FFFFFFFF 2F3F: FFFFFFFF 2F43: FFFFFFFF 2F47: FFFFFFFF 2F4B: FFFFFFFF 2F4F: FFFFFFFF 2F53: FFFFFFFF 2F57: FFFFFFFF 2F5B: FFFFFFFF 2F5F: FFFFFFFF 2F63: FFFFFFFF 2F67: FFFFFFFF 2F6B: FFFFFFFF 2F6F: FFFFFFFF 2F73: FFFFFFFF 2F77: FFFFFFFF 2F7B: FFFFFFFF 2F7F: FFFFFFFF 2F83: FFFFFFFF 2F87: FFFFFFFF 2F8B: FFFFFFFF 2F8F: FFFFFFFF 2F93: FFFFFFFF 2F97: FFFFFFFF 2F9B: FFFFFFFF 2F9F: FFFFFFFF 2FA3: FFFFFFFF 2FA7: FFFFFFFF 2FAB: FFFFFFFF 2FAF: FFFFFFFF 2FB3: FFFFFFFF 2FB7: FFFFFFFF 2FBB: FFFFFFFF 2FBF: FFFFFFFF 2FC3: FFFFFFFF 2FC7: FFFFFFFF 2FCB: FFFFFFFF 2FCF: FFFFFFFF 2FD3: FFFFFFFF 2FD7: FFFFFFFF 2FDB: FFFFFFFF 2FDF: FFFFFFFF 2FE3: FFFFFFFF 2FE7: FFFFFFFF 2FEB: FFFFFFFF 2FEF: FFFFFFFF 2FF3: FFFFFFFF 2FF7: FFFFFFFF 2FFB: FFFFFFFF 2FFF: FFFFFFFF 3003: FFFFFFFF 3007: FFFFFFFF 300B: FFFFFFFF 300F: FFFFFFFF 3013: FFFFFFFF 3017: FFFFFFFF 301B: FFFFFFFF 301F: FFFFFFFF 3023: FFFFFFFF 3027: FFFFFFFF 302B: FFFFFFFF 302F: FFFFFFFF 3033: FFFFFFFF 3037: FFFFFFFF 303B: FFFFFFFF 303F: FFFFFFFF 3043: FFFFFFFF 3047: FFFFFFFF 304B: FFFFFFFF 304F: FFFFFFFF 3053: FFFFFFFF 3057: FFFFFFFF 305B: FFFFFFFF 305F: FFFFFFFF 3063: FFFFFFFF 3067: FFFFFFFF 306B: FFFFFFFF 306F: FFFFFFFF 3073: FFFFFFFF 3077: FFFFFFFF 307B: FFFFFFFF 307F: FFFFFFFF 3083: FFFFFFFF 3087: FFFFFFFF 308B: FFFFFFFF 308F: FFFFFFFF 3093: FFFFFFFF 3097: FFFFFFFF 309B: FFFFFFFF 309F: FFFFFFFF 30A3: FFFFFFFF 30A7: FFFFFFFF 30AB: FFFFFFFF 30AF: FFFFFFFF 30B3: FFFFFFFF 30B7: FFFFFFFF 30BB: FFFFFFFF 30BF: FFFFFFFF 30C3: FFFFFFFF 30C7: FFFFFFFF 30CB: FFFFFFFF 30CF: FFFFFFFF 30D3: FFFFFFFF 30D7: FFFFFFFF 30DB: FFFFFFFF 30DF: FFFFFFFF 30E3: FFFFFFFF 30E7: FFFFFFFF 30EB: FFFFFFFF 30EF: FFFFFFFF 30F3: FFFFFFFF 30F7: FFFFFFFF 30FB: FFFFFFFF 30FF: FFFFFFFF 3103: FFFFFFFF 3107: FFFFFFFF 310B: FFFFFFFF 310F: FFFFFFFF 3113: FFFFFFFF 3117: FFFFFFFF 311B: FFFFFFFF 311F: FFFFFFFF 3123: FFFFFFFF 3127: FFFFFFFF 312B: FFFFFFFF 312F: FFFFFFFF 3133: FFFFFFFF 3137: FFFFFFFF 313B: FFFFFFFF 313F: FFFFFFFF 3143: FFFFFFFF 3147: FFFFFFFF 314B: FFFFFFFF 314F: FFFFFFFF 3153: FFFFFFFF 3157: FFFFFFFF 315B: FFFFFFFF 315F: FFFFFFFF 3163: FFFFFFFF 3167: FFFFFFFF 316B: FFFFFFFF 316F: FFFFFFFF 3173: FFFFFFFF 3177: FFFFFFFF 317B: FFFFFFFF 317F: FFFFFFFF 3183: FFFFFFFF 3187: FFFFFFFF 318B: FFFFFFFF 318F: FFFFFFFF 3193: FFFFFFFF 3197: FFFFFFFF 319B: FFFFFFFF 319F: FFFFFFFF 31A3: FFFFFFFF 31A7: FFFFFFFF 31AB: FFFFFFFF 31AF: FFFFFFFF 31B3: FFFFFFFF 31B7: FFFFFFFF 31BB: FFFFFFFF 31BF: FFFFFFFF 31C3: FFFFFFFF 31C7: FFFFFFFF 31CB: FFFFFFFF 31CF: FFFFFFFF 31D3: FFFFFFFF 31D7: FFFFFFFF 31DB: FFFFFFFF 31DF: FFFFFFFF 31E3: FFFFFFFF 31E7: FFFFFFFF 31EB: FFFFFFFF 31EF: FFFFFFFF 31F3: FFFFFFFF 31F7: FFFFFFFF 31FB: FFFFFFFF 31FF: FFFFFFFF 3203: FFFFFFFF 3207: FFFFFFFF 320B: FFFFFFFF 320F: FFFFFFFF 3213: FFFFFFFF 3217: FFFFFFFF 321B: FFFFFFFF 321F: FFFFFFFF 3223: FFFFFFFF 3227: FFFFFFFF 322B: FFFFFFFF 322F: FFFFFFFF 3233: FFFFFFFF 3237: FFFFFFFF 323B: FFFFFFFF 323F: FFFFFFFF 3243: FFFFFFFF 3247: FFFFFFFF 324B: FFFFFFFF 324F: FFFFFFFF 3253: FFFFFFFF 3257: FFFFFFFF 325B: FFFFFFFF 325F: FFFFFFFF 3263: FFFFFFFF 3267: FFFFFFFF 326B: FFFFFFFF 326F: FFFFFFFF 3273: FFFFFFFF 3277: FFFFFFFF 327B: FFFFFFFF 327F: FFFFFFFF 3283: FFFFFFFF 3287: FFFFFFFF 328B: FFFFFFFF 328F: FFFFFFFF 3293: FFFFFFFF 3297: FFFFFFFF 329B: FFFFFFFF 329F: FFFFFFFF 32A3: FFFFFFFF 32A7: FFFFFFFF 32AB: FFFFFFFF 32AF: FFFFFFFF 32B3: FFFFFFFF 32B7: FFFFFFFF 32BB: FFFFFFFF 32BF: FFFFFFFF 32C3: FFFFFFFF 32C7: FFFFFFFF 32CB: FFFFFFFF 32CF: FFFFFFFF 32D3: FFFFFFFF 32D7: FFFFFFFF 32DB: FFFFFFFF 32DF: FFFFFFFF 32E3: FFFFFFFF 32E7: FFFFFFFF 32EB: FFFFFFFF 32EF: FFFFFFFF 32F3: FFFFFFFF 32F7: FFFFFFFF 32FB: FFFFFFFF 32FF: FFFFFFFF 3303: FFFFFFFF 3307: FFFFFFFF 330B: FFFFFFFF 330F: FFFFFFFF 3313: FFFFFFFF 3317: FFFFFFFF 331B: FFFFFFFF 331F: FFFFFFFF 3323: FFFFFFFF 3327: FFFFFFFF 332B: FFFFFFFF 332F: FFFFFFFF 3333: FFFFFFFF 3337: FFFFFFFF 333B: FFFFFFFF 333F: FFFFFFFF 3343: FFFFFFFF 3347: FFFFFFFF 334B: FFFFFFFF 334F: FFFFFFFF 3353: FFFFFFFF 3357: FFFFFFFF 335B: FFFFFFFF 335F: FFFFFFFF 3363: FFFFFFFF 3367: FFFFFFFF 336B: FFFFFFFF 336F: FFFFFFFF 3373: FFFFFFFF 3377: FFFFFFFF 337B: FFFFFFFF 337F: FFFFFFFF 3383: FFFFFFFF 3387: FFFFFFFF 338B: FFFFFFFF 338F: FFFFFFFF 3393: FFFFFFFF 3397: FFFFFFFF 339B: FFFFFFFF 339F: FFFFFFFF 33A3: FFFFFFFF 33A7: FFFFFFFF 33AB: FFFFFFFF 33AF: FFFFFFFF 33B3: FFFFFFFF 33B7: FFFFFFFF 33BB: FFFFFFFF 33BF: FFFFFFFF 33C3: FFFFFFFF 33C7: FFFFFFFF 33CB: FFFFFFFF 33CF: FFFFFFFF 33D3: FFFFFFFF 33D7: FFFFFFFF 33DB: FFFFFFFF 33DF: FFFFFFFF 33E3: FFFFFFFF 33E7: FFFFFFFF 33EB: FFFFFFFF 33EF: FFFFFFFF 33F3: FFFFFFFF 33F7: FFFFFFFF 33FB: FFFFFFFF 33FF: FFFFFFFF 3403: FFFFFFFF 3407: FFFFFFFF 340B: FFFFFFFF 340F: FFFFFFFF 3413: FFFFFFFF 3417: FFFFFFFF 341B: FFFFFFFF 341F: FFFFFFFF 3423: FFFFFFFF 3427: FFFFFFFF 342B: FFFFFFFF 342F: FFFFFFFF 3433: FFFFFFFF 3437: FFFFFFFF 343B: FFFFFFFF 343F: FFFFFFFF 3443: FFFFFFFF 3447: FFFFFFFF 344B: FFFFFFFF 344F: FFFFFFFF 3453: FFFFFFFF 3457: FFFFFFFF 345B: FFFFFFFF 345F: FFFFFFFF 3463: FFFFFFFF 3467: FFFFFFFF 346B: FFFFFFFF 346F: FFFFFFFF 3473: FFFFFFFF 3477: FFFFFFFF 347B: FFFFFFFF 347F: FFFFFFFF 3483: FFFFFFFF 3487: FFFFFFFF 348B: FFFFFFFF 348F: FFFFFFFF 3493: FFFFFFFF 3497: FFFFFFFF 349B: FFFFFFFF 349F: FFFFFFFF 34A3: FFFFFFFF 34A7: FFFFFFFF 34AB: FFFFFFFF 34AF: FFFFFFFF 34B3: FFFFFFFF 34B7: FFFFFFFF 34BB: FFFFFFFF 34BF: FFFFFFFF 34C3: FFFFFFFF 34C7: FFFFFFFF 34CB: FFFFFFFF 34CF: FFFFFFFF 34D3: FFFFFFFF 34D7: FFFFFFFF 34DB: FFFFFFFF 34DF: FFFFFFFF 34E3: FFFFFFFF 34E7: FFFFFFFF 34EB: FFFFFFFF 34EF: FFFFFFFF 34F3: FFFFFFFF 34F7: FFFFFFFF 34FB: FFFFFFFF 34FF: FFFFFFFF 3503: FFFFFFFF 3507: FFFFFFFF 350B: FFFFFFFF 350F: FFFFFFFF 3513: FFFFFFFF 3517: FFFFFFFF 351B: FFFFFFFF 351F: FFFFFFFF 3523: FFFFFFFF 3527: FFFFFFFF 352B: FFFFFFFF 352F: FFFFFFFF 3533: FFFFFFFF 3537: FFFFFFFF 353B: FFFFFFFF 353F: FFFFFFFF 3543: FFFFFFFF 3547: FFFFFFFF 354B: FFFFFFFF 354F: FFFFFFFF 3553: FFFFFFFF 3557: FFFFFFFF 355B: FFFFFFFF 355F: FFFFFFFF 3563: FFFFFFFF 3567: FFFFFFFF 356B: FFFFFFFF 356F: FFFFFFFF 3573: FFFFFFFF 3577: FFFFFFFF 357B: FFFFFFFF 357F: FFFFFFFF 3583: FFFFFFFF 3587: FFFFFFFF 358B: FFFFFFFF 358F: FFFFFFFF 3593: FFFFFFFF 3597: FFFFFFFF 359B: FFFFFFFF 359F: FFFFFFFF 35A3: FFFFFFFF 35A7: FFFFFFFF 35AB: FFFFFFFF 35AF: FFFFFFFF 35B3: FFFFFFFF 35B7: FFFFFFFF 35BB: FFFFFFFF 35BF: FFFFFFFF 35C3: FFFFFFFF 35C7: FFFFFFFF 35CB: FFFFFFFF 35CF: FFFFFFFF 35D3: FFFFFFFF 35D7: FFFFFFFF 35DB: FFFFFFFF 35DF: FFFFFFFF 35E3: FFFFFFFF 35E7: FFFFFFFF 35EB: FFFFFFFF 35EF: FFFFFFFF 35F3: FFFFFFFF 35F7: FFFFFFFF 35FB: FFFFFFFF 35FF: FFFFFFFF 3603: FFFFFFFF 3607: FFFFFFFF 360B: FFFFFFFF 360F: FFFFFFFF 3613: FFFFFFFF 3617: FFFFFFFF 361B: FFFFFFFF 361F: FFFFFFFF 3623: FFFFFFFF 3627: FFFFFFFF 362B: FFFFFFFF 362F: FFFFFFFF 3633: FFFFFFFF 3637: FFFFFFFF 363B: FFFFFFFF 363F: FFFFFFFF 3643: FFFFFFFF 3647: FFFFFFFF 364B: FFFFFFFF 364F: FFFFFFFF 3653: FFFFFFFF 3657: FFFFFFFF 365B: FFFFFFFF 365F: FFFFFFFF 3663: FFFFFFFF 3667: FFFFFFFF 366B: FFFFFFFF 366F: FFFFFFFF 3673: FFFFFFFF 3677: FFFFFFFF 367B: FFFFFFFF 367F: FFFFFFFF 3683: FFFFFFFF 3687: FFFFFFFF 368B: FFFFFFFF 368F: FFFFFFFF 3693: FFFFFFFF 3697: FFFFFFFF 369B: FFFFFFFF 369F: FFFFFFFF 36A3: FFFFFFFF 36A7: FFFFFFFF 36AB: FFFFFFFF 36AF: FFFFFFFF 36B3: FFFFFFFF 36B7: FFFFFFFF 36BB: FFFFFFFF 36BF: FFFFFFFF 36C3: FFFFFFFF 36C7: FFFFFFFF 36CB: FFFFFFFF 36CF: FFFFFFFF 36D3: FFFFFFFF 36D7: FFFFFFFF 36DB: FFFFFFFF 36DF: FFFFFFFF 36E3: FFFFFFFF 36E7: FFFFFFFF 36EB: FFFFFFFF 36EF: FFFFFFFF 36F3: FFFFFFFF 36F7: FFFFFFFF 36FB: FFFFFFFF 36FF: FFFFFFFF 3703: FFFFFFFF 3707: FFFFFFFF 370B: FFFFFFFF 370F: FFFFFFFF 3713: FFFFFFFF 3717: FFFFFFFF 371B: FFFFFFFF 371F: FFFFFFFF 3723: FFFFFFFF 3727: FFFFFFFF 372B: FFFFFFFF 372F: FFFFFFFF 3733: FFFFFFFF 3737: FFFFFFFF 373B: FFFFFFFF 373F: FFFFFFFF 3743: FFFFFFFF 3747: FFFFFFFF 374B: FFFFFFFF 374F: FFFFFFFF 3753: FFFFFFFF 3757: FFFFFFFF 375B: FFFFFFFF 375F: FFFFFFFF 3763: FFFFFFFF 3767: FFFFFFFF 376B: FFFFFFFF 376F: FFFFFFFF 3773: FFFFFFFF 3777: FFFFFFFF 377B: FFFFFFFF 377F: FFFFFFFF 3783: FFFFFFFF 3787: FFFFFFFF 378B: FFFFFFFF 378F: FFFFFFFF 3793: FFFFFFFF 3797: FFFFFFFF 379B: FFFFFFFF 379F: FFFFFFFF 37A3: FFFFFFFF 37A7: FFFFFFFF 37AB: FFFFFFFF 37AF: FFFFFFFF 37B3: FFFFFFFF 37B7: FFFFFFFF 37BB: FFFFFFFF 37BF: FFFFFFFF 37C3: FFFFFFFF 37C7: FFFFFFFF 37CB: FFFFFFFF 37CF: FFFFFFFF 37D3: FFFFFFFF 37D7: FFFFFFFF 37DB: FFFFFFFF 37DF: FFFFFFFF 37E3: FFFFFFFF 37E7: FFFFFFFF 37EB: FFFFFFFF 37EF: FFFFFFFF 37F3: FFFFFFFF 37F7: FFFFFFFF 37FB: FFFFFFFF 37FF: FFFFFFFF 3803: FFFFFFFF 3807: FFFFFFFF 380B: FFFFFFFF 380F: FFFFFFFF 3813: FFFFFFFF 3817: FFFFFFFF 381B: FFFFFFFF 381F: FFFFFFFF 3823: FFFFFFFF 3827: FFFFFFFF 382B: FFFFFFFF 382F: FFFFFFFF 3833: FFFFFFFF 3837: FFFFFFFF 383B: FFFFFFFF 383F: FFFFFFFF 3843: FFFFFFFF 3847: FFFFFFFF 384B: FFFFFFFF 384F: FFFFFFFF 3853: FFFFFFFF 3857: FFFFFFFF 385B: FFFFFFFF 385F: FFFFFFFF 3863: FFFFFFFF 3867: FFFFFFFF 386B: FFFFFFFF 386F: FFFFFFFF 3873: FFFFFFFF 3877: FFFFFFFF 387B: FFFFFFFF 387F: FFFFFFFF 3883: FFFFFFFF 3887: FFFFFFFF 388B: FFFFFFFF 388F: FFFFFFFF 3893: FFFFFFFF 3897: FFFFFFFF 389B: FFFFFFFF 389F: FFFFFFFF 38A3: FFFFFFFF 38A7: FFFFFFFF 38AB: FFFFFFFF 38AF: FFFFFFFF 38B3: FFFFFFFF 38B7: FFFFFFFF 38BB: FFFFFFFF 38BF: FFFFFFFF 38C3: FFFFFFFF 38C7: FFFFFFFF 38CB: FFFFFFFF 38CF: FFFFFFFF 38D3: FFFFFFFF 38D7: FFFFFFFF 38DB: FFFFFFFF 38DF: FFFFFFFF 38E3: FFFFFFFF 38E7: FFFFFFFF 38EB: FFFFFFFF 38EF: FFFFFFFF 38F3: FFFFFFFF 38F7: FFFFFFFF 38FB: FFFFFFFF 38FF: FFFFFFFF 3903: FFFFFFFF 3907: FFFFFFFF 390B: FFFFFFFF 390F: FFFFFFFF 3913: FFFFFFFF 3917: FFFFFFFF 391B: FFFFFFFF 391F: FFFFFFFF 3923: FFFFFFFF 3927: FFFFFFFF 392B: FFFFFFFF 392F: FFFFFFFF 3933: FFFFFFFF 3937: FFFFFFFF 393B: FFFFFFFF 393F: FFFFFFFF 3943: FFFFFFFF 3947: FFFFFFFF 394B: FFFFFFFF 394F: FFFFFFFF 3953: FFFFFFFF 3957: FFFFFFFF 395B: FFFFFFFF 395F: FFFFFFFF 3963: FFFFFFFF 3967: FFFFFFFF 396B: FFFFFFFF 396F: FFFFFFFF 3973: FFFFFFFF 3977: FFFFFFFF 397B: FFFFFFFF 397F: FFFFFFFF 3983: FFFFFFFF 3987: FFFFFFFF 398B: FFFFFFFF 398F: FFFFFFFF 3993: FFFFFFFF 3997: FFFFFFFF 399B: FFFFFFFF 399F: FFFFFFFF 39A3: FFFFFFFF 39A7: FFFFFFFF 39AB: FFFFFFFF 39AF: FFFFFFFF 39B3: FFFFFFFF 39B7: FFFFFFFF 39BB: FFFFFFFF 39BF: FFFFFFFF 39C3: FFFFFFFF 39C7: FFFFFFFF 39CB: FFFFFFFF 39CF: FFFFFFFF 39D3: FFFFFFFF 39D7: FFFFFFFF 39DB: FFFFFFFF 39DF: FFFFFFFF 39E3: FFFFFFFF 39E7: FFFFFFFF 39EB: FFFFFFFF 39EF: FFFFFFFF 39F3: FFFFFFFF 39F7: FFFFFFFF 39FB: FFFFFFFF 39FF: FFFFFFFF 3A03: FFFFFFFF 3A07: FFFFFFFF 3A0B: FFFFFFFF 3A0F: FFFFFFFF 3A13: FFFFFFFF 3A17: FFFFFFFF 3A1B: FFFFFFFF 3A1F: FFFFFFFF 3A23: FFFFFFFF 3A27: FFFFFFFF 3A2B: FFFFFFFF 3A2F: FFFFFFFF 3A33: FFFFFFFF 3A37: FFFFFFFF 3A3B: FFFFFFFF 3A3F: FFFFFFFF 3A43: FFFFFFFF 3A47: FFFFFFFF 3A4B: FFFFFFFF 3A4F: FFFFFFFF 3A53: FFFFFFFF 3A57: FFFFFFFF 3A5B: FFFFFFFF 3A5F: FFFFFFFF 3A63: FFFFFFFF 3A67: FFFFFFFF 3A6B: FFFFFFFF 3A6F: FFFFFFFF 3A73: FFFFFFFF 3A77: FFFFFFFF 3A7B: FFFFFFFF 3A7F: FFFFFFFF 3A83: FFFFFFFF 3A87: FFFFFFFF 3A8B: FFFFFFFF 3A8F: FFFFFFFF 3A93: FFFFFFFF 3A97: FFFFFFFF 3A9B: FFFFFFFF 3A9F: FFFFFFFF 3AA3: FFFFFFFF 3AA7: FFFFFFFF 3AAB: FFFFFFFF 3AAF: FFFFFFFF 3AB3: FFFFFFFF 3AB7: FFFFFFFF 3ABB: FFFFFFFF 3ABF: FFFFFFFF 3AC3: FFFFFFFF 3AC7: FFFFFFFF 3ACB: FFFFFFFF 3ACF: FFFFFFFF 3AD3: FFFFFFFF 3AD7: FFFFFFFF 3ADB: FFFFFFFF 3ADF: FFFFFFFF 3AE3: FFFFFFFF 3AE7: FFFFFFFF 3AEB: FFFFFFFF 3AEF: FFFFFFFF 3AF3: FFFFFFFF 3AF7: FFFFFFFF 3AFB: FFFFFFFF 3AFF: FFFFFFFF 3B03: FFFFFFFF 3B07: FFFFFFFF 3B0B: FFFFFFFF 3B0F: FFFFFFFF 3B13: FFFFFFFF 3B17: FFFFFFFF 3B1B: FFFFFFFF 3B1F: FFFFFFFF 3B23: FFFFFFFF 3B27: FFFFFFFF 3B2B: FFFFFFFF 3B2F: FFFFFFFF 3B33: FFFFFFFF 3B37: FFFFFFFF 3B3B: FFFFFFFF 3B3F: FFFFFFFF 3B43: FFFFFFFF 3B47: FFFFFFFF 3B4B: FFFFFFFF 3B4F: FFFFFFFF 3B53: FFFFFFFF 3B57: FFFFFFFF 3B5B: FFFFFFFF 3B5F: FFFFFFFF 3B63: FFFFFFFF 3B67: FFFFFFFF 3B6B: FFFFFFFF 3B6F: FFFFFFFF 3B73: FFFFFFFF 3B77: FFFFFFFF 3B7B: FFFFFFFF 3B7F: FFFFFFFF 3B83: FFFFFFFF 3B87: FFFFFFFF 3B8B: FFFFFFFF 3B8F: FFFFFFFF 3B93: FFFFFFFF 3B97: FFFFFFFF 3B9B: FFFFFFFF 3B9F: FFFFFFFF 3BA3: FFFFFFFF 3BA7: FFFFFFFF 3BAB: FFFFFFFF 3BAF: FFFFFFFF 3BB3: FFFFFFFF 3BB7: FFFFFFFF 3BBB: FFFFFFFF 3BBF: FFFFFFFF 3BC3: FFFFFFFF 3BC7: FFFFFFFF 3BCB: FFFFFFFF 3BCF: FFFFFFFF 3BD3: FFFFFFFF 3BD7: FFFFFFFF 3BDB: FFFFFFFF 3BDF: FFFFFFFF 3BE3: FFFFFFFF 3BE7: FFFFFFFF 3BEB: FFFFFFFF 3BEF: FFFFFFFF 3BF3: FFFFFFFF 3BF7: FFFFFFFF 3BFB: FFFFFFFF 3BFF: FFFFFFFF 3C03: FFFFFFFF 3C07: FFFFFFFF 3C0B: FFFFFFFF 3C0F: FFFFFFFF 3C13: FFFFFFFF 3C17: FFFFFFFF 3C1B: FFFFFFFF 3C1F: FFFFFFFF 3C23: FFFFFFFF 3C27: FFFFFFFF 3C2B: FFFFFFFF 3C2F: FFFFFFFF 3C33: FFFFFFFF 3C37: FFFFFFFF 3C3B: FFFFFFFF 3C3F: FFFFFFFF 3C43: FFFFFFFF 3C47: FFFFFFFF 3C4B: FFFFFFFF 3C4F: FFFFFFFF 3C53: FFFFFFFF 3C57: FFFFFFFF 3C5B: FFFFFFFF 3C5F: FFFFFFFF 3C63: FFFFFFFF 3C67: FFFFFFFF 3C6B: FFFFFFFF 3C6F: FFFFFFFF 3C73: FFFFFFFF 3C77: FFFFFFFF 3C7B: FFFFFFFF 3C7F: FFFFFFFF 3C83: FFFFFFFF 3C87: FFFFFFFF 3C8B: FFFFFFFF 3C8F: FFFFFFFF 3C93: FFFFFFFF 3C97: FFFFFFFF 3C9B: FFFFFFFF 3C9F: FFFFFFFF 3CA3: FFFFFFFF 3CA7: FFFFFFFF 3CAB: FFFFFFFF 3CAF: FFFFFFFF 3CB3: FFFFFFFF 3CB7: FFFFFFFF 3CBB: FFFFFFFF 3CBF: FFFFFFFF 3CC3: FFFFFFFF 3CC7: FFFFFFFF 3CCB: FFFFFFFF 3CCF: FFFFFFFF 3CD3: FFFFFFFF 3CD7: FFFFFFFF 3CDB: FFFFFFFF 3CDF: FFFFFFFF 3CE3: FFFFFFFF 3CE7: FFFFFFFF 3CEB: FFFFFFFF 3CEF: FFFFFFFF 3CF3: FFFFFFFF 3CF7: FFFFFFFF 3CFB: FFFFFFFF 3CFF: FFFFFFFF 3D03: FFFFFFFF 3D07: FFFFFFFF 3D0B: FFFFFFFF 3D0F: FFFFFFFF 3D13: FFFFFFFF 3D17: FFFFFFFF 3D1B: FFFFFFFF 3D1F: FFFFFFFF 3D23: FFFFFFFF 3D27: FFFFFFFF 3D2B: FFFFFFFF 3D2F: FFFFFFFF 3D33: FFFFFFFF 3D37: FFFFFFFF 3D3B: FFFFFFFF 3D3F: FFFFFFFF 3D43: FFFFFFFF 3D47: FFFFFFFF 3D4B: FFFFFFFF 3D4F: FFFFFFFF 3D53: FFFFFFFF 3D57: FFFFFFFF 3D5B: FFFFFFFF 3D5F: FFFFFFFF 3D63: FFFFFFFF 3D67: FFFFFFFF 3D6B: FFFFFFFF 3D6F: FFFFFFFF 3D73: FFFFFFFF 3D77: FFFFFFFF 3D7B: FFFFFFFF 3D7F: FFFFFFFF 3D83: FFFFFFFF 3D87: FFFFFFFF 3D8B: FFFFFFFF 3D8F: FFFFFFFF 3D93: FFFFFFFF 3D97: FFFFFFFF 3D9B: FFFFFFFF 3D9F: FFFFFFFF 3DA3: FFFFFFFF 3DA7: FFFFFFFF 3DAB: FFFFFFFF 3DAF: FFFFFFFF 3DB3: FFFFFFFF 3DB7: FFFFFFFF 3DBB: FFFFFFFF 3DBF: FFFFFFFF 3DC3: FFFFFFFF 3DC7: FFFFFFFF 3DCB: FFFFFFFF 3DCF: FFFFFFFF 3DD3: FFFFFFFF 3DD7: FFFFFFFF 3DDB: FFFFFFFF 3DDF: FFFFFFFF 3DE3: FFFFFFFF 3DE7: FFFFFFFF 3DEB: FFFFFFFF 3DEF: FFFFFFFF 3DF3: FFFFFFFF 3DF7: FFFFFFFF 3DFB: FFFFFFFF 3DFF: FFFFFFFF 3E03: FFFFFFFF 3E07: FFFFFFFF 3E0B: FFFFFFFF 3E0F: FFFFFFFF 3E13: FFFFFFFF 3E17: FFFFFFFF 3E1B: FFFFFFFF 3E1F: FFFFFFFF 3E23: FFFFFFFF 3E27: FFFFFFFF 3E2B: FFFFFFFF 3E2F: FFFFFFFF 3E33: FFFFFFFF 3E37: FFFFFFFF 3E3B: FFFFFFFF 3E3F: FFFFFFFF 3E43: FFFFFFFF 3E47: FFFFFFFF 3E4B: FFFFFFFF 3E4F: FFFFFFFF 3E53: FFFFFFFF 3E57: FFFFFFFF 3E5B: FFFFFFFF 3E5F: FFFFFFFF 3E63: FFFFFFFF 3E67: FFFFFFFF 3E6B: FFFFFFFF 3E6F: FFFFFFFF 3E73: FFFFFFFF 3E77: FFFFFFFF 3E7B: FFFFFFFF 3E7F: FFFFFFFF 3E83: FFFFFFFF 3E87: FFFFFFFF 3E8B: FFFFFFFF 3E8F: FFFFFFFF 3E93: FFFFFFFF 3E97: FFFFFFFF 3E9B: FFFFFFFF 3E9F: FFFFFFFF 3EA3: FFFFFFFF 3EA7: FFFFFFFF 3EAB: FFFFFFFF 3EAF: FFFFFFFF 3EB3: FFFFFFFF 3EB7: FFFFFFFF 3EBB: FFFFFFFF 3EBF: FFFFFFFF 3EC3: FFFFFFFF 3EC7: FFFFFFFF 3ECB: FFFFFFFF 3ECF: FFFFFFFF 3ED3: FFFFFFFF 3ED7: FFFFFFFF 3EDB: FFFFFFFF 3EDF: FFFFFFFF 3EE3: FFFFFFFF 3EE7: FFFFFFFF 3EEB: FFFFFFFF 3EEF: FFFFFFFF 3EF3: FFFFFFFF 3EF7: FFFFFFFF 3EFB: FFFFFFFF 3EFF: FFFFFFFF 3F03: FFFFFFFF 3F07: FFFFFFFF 3F0B: FFFFFFFF 3F0F: FFFFFFFF 3F13: FFFFFFFF 3F17: FFFFFFFF 3F1B: FFFFFFFF 3F1F: FFFFFFFF 3F23: FFFFFFFF 3F27: FFFFFFFF 3F2B: FFFFFFFF 3F2F: FFFFFFFF 3F33: FFFFFFFF 3F37: FFFFFFFF 3F3B: FFFFFFFF 3F3F: FFFFFFFF 3F43: FFFFFFFF 3F47: FFFFFFFF 3F4B: FFFFFFFF 3F4F: FFFFFFFF 3F53: FFFFFFFF 3F57: FFFFFFFF 3F5B: FFFFFFFF 3F5F: FFFFFFFF 3F63: FFFFFFFF 3F67: FFFFFFFF 3F6B: FFFFFFFF 3F6F: FFFFFFFF 3F73: FFFFFFFF 3F77: FFFFFFFF 3F7B: FFFFFFFF 3F7F: FFFFFFFF 3F83: FFFFFFFF 3F87: FFFFFFFF 3F8B: FFFFFFFF 3F8F: FFFFFFFF 3F93: FFFFFFFF 3F97: FFFFFFFF 3F9B: FFFFFFFF 3F9F: FFFFFFFF 3FA3: FFFFFFFF 3FA7: FFFFFFFF 3FAB: FFFFFFFF 3FAF: FFFFFFFF 3FB3: FFFFFFFF 3FB7: FFFFFFFF 3FBB: FFFFFFFF 3FBF: FFFFFFFF 3FC3: FFFFFFFF 3FC7: FFFFFFFF 3FCB: FFFFFFFF 3FCF: FFFFFFFF 3FD3: FFFFFFFF 3FD7: FFFFFFFF 3FDB: FFFFFFFF 3FDF: FFFFFFFF 3FE3: FFFFFFFF 3FE7: FFFFFFFF 3FEB: FFFFFFFF 3FEF: FFFFFFFF 3FF3: FFFFFFFF 3FF7: FFFFFFFF 3FFB: FFFFFFFF 3FFF: FF code_end defs $4000-$ 4000: data_end data 0 4000: 4000: 4000: 4000: 4000: #end ; ((inserted by zasm)) ; +++ defined symbols +++ data_size equ $0400 ; = 1024 data_buffer equ $5B00 ; = 23296 port equ $FFFFFFEF ; = -17 port_A8 equ $FFFFFEEF ; = -273 port_A9 equ $FFFFFDEF ; = -529 port_A10 equ $FFFFFBEF ; = -1041 port_A11 equ $FFFFF7EF ; = -2065 port_A12 equ $FFFFEFEF ; = -4113 port_A13 equ $FFFFDFEF ; = -8209 all_ports equ $FFFFC0EF ; = -16145 print_msg_no_exx equ $0008 ; = 8 print_msg equ $0008 ; = 8 save_registers equ $0010 ; = 16 jp_ix equ $0013 ; = 19 jp_iy equ $0015 ; = 21 save_exx_registers equ $0018 ; = 24 jp_de equ $001B ; = 27 jp_bc equ $001D ; = 29 jp_hl equ $001F ; = 31 vip equ $0020 ; = 32 vip_iy equ $0021 ; = 33 save_registers_ctd equ $004B ; = 75 save_exx_registers_ctd equ $0059 ; = 89 RAMTOP equ $5B00 ; = 23296 cold_start_ctd equ $006B ; = 107 cold_1 equ $007B ; = 123 inkey_dispatcher equ $00A2 ; = 162 sk1 equ $00A7 ; = 167 sk2 equ $00B4 ; = 180 sk3 equ $00BA ; = 186 main equ $00BE ; = 190 main_menu equ $00BE ; = 190 mm1 equ $0199 ; = 409 ram_test_menu equ $01C0 ; = 448 rt1 equ $0255 ; = 597 eprom_test_menu equ $0267 ; = 615 et1 equ $0304 ; = 772 ttl_test_menu equ $0316 ; = 790 tt1 equ $03B4 ; = 948 print_start equ $03C6 ; = 966 p_scratch equ $5B02 ; = 23298 print_first_data equ $5B0C ; = 23308 print_hl equ $5B0C ; = 23308 print_c equ $5B0E ; = 23310 print_attr equ $5B0F ; = 23311 print_flags equ $5B10 ; = 23312 print_scrollcount equ $5B11 ; = 23313 print_logptr equ $5B12 ; = 23314 print_pending_ctl equ $5B14 ; = 23316 print_last_data equ $5B16 ; = 23318 pbit_narrow equ $0000 ; = 0 pbit_inverse equ $0001 ; = 1 pbit_bold equ $0002 ; = 2 pbit_log equ $0003 ; = 3 pbit_pending_ctl equ $0004 ; = 4 black equ $0000 ; = 0 blue equ $0001 ; = 1 red equ $0002 ; = 2 magenta equ $0003 ; = 3 green equ $0004 ; = 4 cyan equ $0005 ; = 5 yellow equ $0006 ; = 6 white equ $0007 ; = 7 pen equ $0001 ; = 1 paper equ $0008 ; = 8 bright equ $0040 ; = 64 flashing equ $0080 ; = 128 black_paper equ $0000 ; = 0 blue_paper equ $0008 ; = 8 red_paper equ $0010 ; = 16 magenta_paper equ $0018 ; = 24 green_paper equ $0020 ; = 32 cyan_paper equ $0028 ; = 40 yellow_paper equ $0030 ; = 48 white_paper equ $0038 ; = 56 ctl_eot equ $0000 ; = 0 ctl_home equ $0001 ; = 1 ctl_cls equ $0002 ; = 2 ctl_locate equ $0003 ; = 3 ctl_setcol equ $0004 ; = 4 ctl_setrow equ $0005 ; = 5 ctl_setattr equ $0006 ; = 6 ctl_setpen equ $0007 ; = 7 ctl_setpaper equ $0008 ; = 8 ctl_clrcols equ $0009 ; = 9 ctl_tab equ $000A ; = 10 ctl_newline equ $000D ; = 13 ctl_inverse equ $000E ; = 14 ctl_narrow equ $0010 ; = 16 ctl_bold equ $0012 ; = 18 ctl_log equ $0014 ; = 20 ctl_flash equ $0016 ; = 22 ctl_bright equ $0018 ; = 24 ctl_clr2eol equ $001A ; = 26 init_print equ $03C6 ; = 966 print_reset_no_exx equ $03CC ; = 972 print_reset equ $03CC ; = 972 text_speed_test equ $03D4 ; = 980 print_calc_ctl_args equ $040D ; = 1037 pq1 equ $0417 ; = 1047 pq2 equ $041A ; = 1050 pq0 equ $041D ; = 1053 print_push_state equ $041F ; = 1055 print_pop_state equ $042B ; = 1067 print_yes_no equ $0434 ; = 1076 print_no equ $0436 ; = 1078 print_yes equ $043C ; = 1084 print_dec_a equ $0443 ; = 1091 print_dec equ $0449 ; = 1097 pd1 equ $044A ; = 1098 pd2 equ $0450 ; = 1104 print_vz_dec equ $0458 ; = 1112 print_hex4 equ $0461 ; = 1121 print_hex2 equ $046A ; = 1130 print_hex1 equ $0473 ; = 1139 print_bin16 equ $047F ; = 1151 print_bin8 equ $0486 ; = 1158 print_bin4 equ $048F ; = 1167 access_hlc equ $0498 ; = 1176 ahlc1 equ $04AA ; = 1194 access_return_de equ $04B8 ; = 1208 print_char_no_exx equ $04BC ; = 1212 print_char equ $04BC ; = 1212 print_text_hl_no_exx equ $04C2 ; = 1218 print_text_hl equ $04C2 ; = 1218 pm_1 equ $04C5 ; = 1221 print_text_hlc_no_exx equ $04D1 ; = 1233 print_text_hlc equ $04D1 ; = 1233 print_text_hlbc_no_exx equ $04D3 ; = 1235 print_text_hlbc equ $04D3 ; = 1235 pt_11 equ $04DE ; = 1246 pt_1 equ $04DF ; = 1247 pt_2 equ $04E7 ; = 1255 print_locate_no_exx equ $04F1 ; = 1265 print_locate equ $04F1 ; = 1265 v_locate equ $04FD ; = 1277 print_setrow equ $0509 ; = 1289 pc_l4 equ $0515 ; = 1301 print_setcol equ $0521 ; = 1313 print_setattr equ $052D ; = 1325 scroll_screen_save_exx equ $0531 ; = 1329 scroll_screen equ $0532 ; = 1330 ss1 equ $053E ; = 1342 scroll_screen_up equ $0541 ; = 1345 show_scroll_and_wait_for_key_save_exx equ $054B ; = 1355 show_scroll_and_wait_for_key equ $054C ; = 1356 print_find_word_wrap equ $0582 ; = 1410 pctw1 equ $0589 ; = 1417 pctw3 equ $0594 ; = 1428 pctw4 equ $059A ; = 1434 print_find_char_wrap equ $059E ; = 1438 print_calc_print_width equ $05AD ; = 1453 print_add_print_width equ $05B0 ; = 1456 pcpw equ $05B0 ; = 1456 print_calc_print_width_char equ $05C1 ; = 1473 pc_dd equ $05DC ; = 1500 up_print_char_a_at_hl_bit_c equ $05DE ; = 1502 pc_aa equ $05F1 ; = 1521 pc_ab equ $05FB ; = 1531 up_print_char_de_at_hl_bit_c equ $060D ; = 1549 pc_ba equ $0618 ; = 1560 pc_b equ $0623 ; = 1571 pc_c equ $062A ; = 1578 pc_a equ $0632 ; = 1586 pc_i equ $0637 ; = 1591 pc_g equ $0639 ; = 1593 pc_a2 equ $063C ; = 1596 pc_h equ $0643 ; = 1603 pc_z equ $0646 ; = 1606 print_add_spacing equ $0655 ; = 1621 pc_e equ $065A ; = 1626 pc_d equ $0667 ; = 1639 pc_f equ $0668 ; = 1640 pc_jumpblock equ $0679 ; = 1657 pc_11 equ $06B9 ; = 1721 pc_12 equ $06B9 ; = 1721 pc_27 equ $06B9 ; = 1721 pc_28 equ $06B9 ; = 1721 pc_29 equ $06B9 ; = 1721 pc_30 equ $06B9 ; = 1721 pc_31 equ $06B9 ; = 1721 pc_eot equ $06B9 ; = 1721 pc_flash_off equ $06BB ; = 1723 pc_flash_on equ $06C2 ; = 1730 pc_bright_off equ $06C9 ; = 1737 pc_bright_on equ $06D0 ; = 1744 pc_inverse_off equ $06D7 ; = 1751 pc_inverse_on equ $06DE ; = 1758 pc_narrow_off equ $06E5 ; = 1765 pc_narrow_on equ $06EC ; = 1772 pc_bold_off equ $06F3 ; = 1779 pc_bold_on equ $06FA ; = 1786 pc_log_off equ $0701 ; = 1793 pc_log_on equ $0708 ; = 1800 pc_cls equ $070F ; = 1807 pc_home equ $0715 ; = 1813 pc_tab equ $071F ; = 1823 pc_newline equ $0723 ; = 1827 pc_nl equ $0725 ; = 1829 pc_setpen equ $072F ; = 1839 pc_setpaper equ $0734 ; = 1844 pc_locate equ $0739 ; = 1849 pc_locate_resume equ $073E ; = 1854 pc_setcol equ $0742 ; = 1858 pc_setrow equ $0747 ; = 1863 pc_clrcols equ $074C ; = 1868 pc_clr2eol equ $0751 ; = 1873 pc_setattr equ $0757 ; = 1879 pc_argx equ $075A ; = 1882 pc_clrcols_resume equ $0764 ; = 1892 pc_setpen_resume equ $0768 ; = 1896 pc_setpaper_resume equ $076F ; = 1903 pc_sp_r equ $0777 ; = 1911 pc_setattr_resume equ $077F ; = 1919 pc_setcol_resume equ $0784 ; = 1924 pc_setrow_resume equ $078E ; = 1934 pc_sr1 equ $0799 ; = 1945 print_clear_current_row equ $07A6 ; = 1958 print_clear_row equ $07AC ; = 1964 print_clear_row_hl equ $07B4 ; = 1972 print_clear_row_hl_quick equ $07B5 ; = 1973 pcr_hl equ $07BD ; = 1981 v_clear_cols equ $07C6 ; = 1990 print_clear_cols_no_exx equ $07D7 ; = 2007 print_clear_cols equ $07D7 ; = 2007 pcc1 equ $07E4 ; = 2020 pcc2 equ $07E7 ; = 2023 pcb1 equ $07F0 ; = 2032 up_clear_partial_cell equ $080B ; = 2059 pcb3 equ $080C ; = 2060 pcb2 equ $0813 ; = 2067 pcb4 equ $081D ; = 2077 print_get_row_b_and_col_c equ $082E ; = 2094 calc_row_b_col_c_from_hlc equ $083B ; = 2107 print_set_row_b_and_col_c equ $0864 ; = 2148 calc_hlc_from_row_b_col_c equ $0873 ; = 2163 pmasks equ $0890 ; = 2192 calc_glyph_address equ $0898 ; = 2200 charcode_icursor equ $0094 ; = 148 c20 equ $08A6 ; = 2214 charcode_io equ $0095 ; = 149 c21 equ $08A7 ; = 2215 charcode_gnd equ $0096 ; = 150 c22 equ $08AF ; = 2223 charcode_vcc equ $0097 ; = 151 c23 equ $08B6 ; = 2230 charcode_3state equ $0098 ; = 152 c24 equ $08BD ; = 2237 charcode_oK equ $0099 ; = 153 c25 equ $08C2 ; = 2242 charcode_i_left equ $009A ; = 154 charcode_o_right equ $009A ; = 154 c26 equ $08C7 ; = 2247 charcode_o_left equ $009B ; = 155 charcode_i_right equ $009B ; = 155 c27 equ $08CD ; = 2253 charcode_left_arrow equ $009C ; = 156 c28 equ $08D3 ; = 2259 charcode_down_arrow equ $009D ; = 157 c29 equ $08D9 ; = 2265 charcode_up_arrow equ $009E ; = 158 c30 equ $08E0 ; = 2272 charcode_right_arrow equ $009F ; = 159 c31 equ $08E7 ; = 2279 c32 equ $08ED ; = 2285 charset equ $08EF ; = 2287 c33 equ $08EF ; = 2287 c34 equ $08F0 ; = 2288 c35 equ $08F3 ; = 2291 c36 equ $08F9 ; = 2297 c37 equ $08FE ; = 2302 c38 equ $0904 ; = 2308 c39 equ $090A ; = 2314 c40 equ $090B ; = 2315 c41 equ $090D ; = 2317 c42 equ $090F ; = 2319 c43 equ $0914 ; = 2324 c44 equ $0919 ; = 2329 c45 equ $091B ; = 2331 c46 equ $0920 ; = 2336 c47 equ $0922 ; = 2338 c48 equ $0927 ; = 2343 c49 equ $092C ; = 2348 c50 equ $0931 ; = 2353 c51 equ $0936 ; = 2358 c52 equ $093B ; = 2363 c53 equ $0940 ; = 2368 c54 equ $0945 ; = 2373 c55 equ $094A ; = 2378 c56 equ $094F ; = 2383 c57 equ $0954 ; = 2388 c58 equ $0959 ; = 2393 c59 equ $095A ; = 2394 c60 equ $095C ; = 2396 c61 equ $095F ; = 2399 c62 equ $0963 ; = 2403 c63 equ $0966 ; = 2406 c64 equ $096B ; = 2411 c65 equ $0971 ; = 2417 c66 equ $0976 ; = 2422 c67 equ $097B ; = 2427 c68 equ $0980 ; = 2432 c69 equ $0985 ; = 2437 c70 equ $098A ; = 2442 c71 equ $098F ; = 2447 c72 equ $0994 ; = 2452 c73 equ $0999 ; = 2457 c74 equ $099C ; = 2460 c75 equ $09A0 ; = 2464 c76 equ $09A5 ; = 2469 c77 equ $09A9 ; = 2473 c78 equ $09AF ; = 2479 c79 equ $09B5 ; = 2485 c80 equ $09BB ; = 2491 c81 equ $09C0 ; = 2496 c82 equ $09C6 ; = 2502 c83 equ $09CB ; = 2507 c84 equ $09D0 ; = 2512 c85 equ $09D5 ; = 2517 c86 equ $09DA ; = 2522 c87 equ $09DF ; = 2527 c88 equ $09E5 ; = 2533 c89 equ $09EB ; = 2539 c90 equ $09F0 ; = 2544 c91 equ $09F6 ; = 2550 c92 equ $09F9 ; = 2553 c93 equ $09FE ; = 2558 c94 equ $0A01 ; = 2561 c95 equ $0A06 ; = 2566 c96 equ $0A0A ; = 2570 c97 equ $0A0F ; = 2575 c98 equ $0A14 ; = 2580 c99 equ $0A19 ; = 2585 c100 equ $0A1D ; = 2589 c101 equ $0A22 ; = 2594 c102 equ $0A27 ; = 2599 c103 equ $0A2A ; = 2602 c104 equ $0A2F ; = 2607 c105 equ $0A34 ; = 2612 c106 equ $0A37 ; = 2615 c107 equ $0A3B ; = 2619 c108 equ $0A3F ; = 2623 c109 equ $0A42 ; = 2626 c110 equ $0A49 ; = 2633 c111 equ $0A4E ; = 2638 c112 equ $0A53 ; = 2643 c113 equ $0A58 ; = 2648 c114 equ $0A5D ; = 2653 c115 equ $0A61 ; = 2657 c116 equ $0A66 ; = 2662 c117 equ $0A6A ; = 2666 c118 equ $0A6F ; = 2671 c119 equ $0A74 ; = 2676 c120 equ $0A79 ; = 2681 c121 equ $0A7E ; = 2686 c122 equ $0A82 ; = 2690 c123 equ $0A87 ; = 2695 c124 equ $0A8B ; = 2699 c125 equ $0A8C ; = 2700 c126 equ $0A90 ; = 2704 c127 equ $0A94 ; = 2708 c128 equ $0A9C ; = 2716 charset_ptr equ $0AB7 ; = 2743 print_end equ $0B77 ; = 2935 screen_start equ $0B77 ; = 2935 ula_out_byte equ $5B16 ; = 23318 scr_set_border equ $0B77 ; = 2935 scr_restore_border equ $0B7F ; = 2943 clear_32_bytes equ $0B85 ; = 2949 clear_31_bytes equ $0B87 ; = 2951 clear_0_bytes equ $0BC5 ; = 3013 copy_32_bytes equ $0BC7 ; = 3015 copy_31_bytes equ $0BC9 ; = 3017 copy_0_bytes equ $0C07 ; = 3079 calc_ix_for_clear_c equ $0C09 ; = 3081 calc_ix_for_copy_c equ $0C0F ; = 3087 calc_ix equ $0C13 ; = 3091 clear_bc equ $0C1F ; = 3103 clear_bc_a equ $0C20 ; = 3104 clear_bc_e equ $0C21 ; = 3105 cbc3 equ $0C27 ; = 3111 cbc4 equ $0C2F ; = 3119 cbcx equ $0C35 ; = 3125 cbc5 equ $0C3A ; = 3130 clear_pixels_no_exx equ $0C41 ; = 3137 clear_pixels equ $0C41 ; = 3137 clear_pixels_quick equ $0C46 ; = 3142 cb80 equ $0C52 ; = 3154 cb81 equ $0C55 ; = 3157 clrret equ $0C57 ; = 3159 clear_attributes_no_exx equ $0C64 ; = 3172 clear_attributes equ $0C64 ; = 3172 clear_attributes_quick equ $0C65 ; = 3173 clear_attributes_with_e_quick equ $0C66 ; = 3174 cb84 equ $0C70 ; = 3184 claret equ $0C72 ; = 3186 clear_screen_with_attr_no_exx equ $0C7D ; = 3197 clear_screen_with_attr equ $0C7D ; = 3197 clear_cbox_with_attr_no_exx equ $0C9B ; = 3227 clear_cbox_with_attr equ $0C9B ; = 3227 clear_cbox_with_attr_quick equ $0C9C ; = 3228 copy_bc equ $0CA6 ; = 3238 copy_c equ $0CAA ; = 3242 cpbc5 equ $0CAF ; = 3247 cpbc1 equ $0CBE ; = 3262 cpbc2 equ $0CC2 ; = 3266 cpbc3 equ $0CC8 ; = 3272 cpbc4 equ $0CCC ; = 3276 scr_save_pixels_no_exx equ $0CD2 ; = 3282 scr_save_pixels equ $0CD2 ; = 3282 pcp0 equ $0CF0 ; = 3312 pcp1 equ $0CF5 ; = 3317 pcp1ret equ $0CF7 ; = 3319 scr_save_attributes_no_exx equ $0D03 ; = 3331 scr_save_attributes equ $0D03 ; = 3331 pca0 equ $0D22 ; = 3362 pca1ret equ $0D27 ; = 3367 pop_ixhldebc equ $0D2B ; = 3371 up_store_hlbc_to_de equ $0D31 ; = 3377 v_restore_pixels equ $0D3C ; = 3388 scr_restore_pixels_no_exx equ $0D41 ; = 3393 scr_restore_pixels equ $0D41 ; = 3393 pp0 equ $0D5D ; = 3421 pp1 equ $0D62 ; = 3426 pp1ret equ $0D64 ; = 3428 pop_iyixhldebc_dealloc equ $0D6E ; = 3438 pop_ixhldebc_dealloc equ $0D70 ; = 3440 v_restore_attributes equ $0D76 ; = 3446 scr_restore_attributes_no_exx equ $0D7B ; = 3451 scr_restore_attributes equ $0D7B ; = 3451 ppa3 equ $0D98 ; = 3480 ppa2ret equ $0D9D ; = 3485 scroll_cbox_up_save_exx equ $0DA5 ; = 3493 scroll_cbox_up equ $0DA6 ; = 3494 scroll_cbox_up_quick equ $0DAF ; = 3503 psb0 equ $0DC7 ; = 3527 psb1 equ $0DCE ; = 3534 psb1ret equ $0DD3 ; = 3539 psa1 equ $0DE6 ; = 3558 psa1ret equ $0DEB ; = 3563 psb3 equ $0DF0 ; = 3568 calc_hl_for_next_pixel_row equ $0DFF ; = 3583 adjust_hl_for_next_row equ $0E04 ; = 3588 calc_de_for_next_pixel_row equ $0E0E ; = 3598 adjust_de_for_next_row equ $0E13 ; = 3603 calc_hl_down_8_pixel_rows equ $0E1D ; = 3613 calc_attr_hl_for_pixel_hl equ $0E27 ; = 3623 calc_pixel_hl_for_attr_hl equ $0E31 ; = 3633 calc_attr_hl_for_row_b_col_c equ $0E39 ; = 3641 calc_pixel_hl_for_row_b_col_c equ $0E48 ; = 3656 calc_row_b_col_c_for_pixel_hl equ $0E57 ; = 3671 calc_row_b_col_c_for_attr_hl equ $0E66 ; = 3686 screen_end equ $0E75 ; = 3701 mempack_start equ $0E75 ; = 3701 mem_start equ $5B17 ; = 23319 mem_data_start equ $5B17 ; = 23319 mem_data_end equ $5B19 ; = 23321 mem_free_start equ $5B19 ; = 23321 mem_free_end equ $5B1B ; = 23323 mem_handles_start equ $5B1B ; = 23323 mem_last_handle equ $5B1D ; = 23325 mem_handles_end equ $5B1F ; = 23327 mem_heap_start equ $5B1F ; = 23327 mem_heap_ptr equ $5B21 ; = 23329 mem_stack_ptr equ $5B23 ; = 23331 mem_stack_end equ $5B25 ; = 23333 mem_end equ $5B25 ; = 23333 mem_empty_data equ $0E75 ; = 3701 lo equ $0000 ; = 0 hi equ $0001 ; = 1 mem_max_size equ $6000 ; = 24576 mem_max_hi equ $0060 ; = 96 mem_init equ $0E77 ; = 3703 v_mem_compact equ $0E99 ; = 3737 mem_compact equ $0E9B ; = 3739 mc0 equ $0EAD ; = 3757 mc1 equ $0EE4 ; = 3812 mem_compact_loop1 equ $0EFD ; = 3837 mc1e equ $0EFD ; = 3837 mc2 equ $0F08 ; = 3848 mc3 equ $0F12 ; = 3858 mc2ee equ $0F25 ; = 3877 mem_compact_loop2 equ $0F26 ; = 3878 mc2e equ $0F26 ; = 3878 mem_get_free_total equ $0F31 ; = 3889 mem_get_free equ $0F34 ; = 3892 mem_get_size_and_address equ $0F47 ; = 3911 v_mem_get_size equ $0F50 ; = 3920 mem_get_size_de_and_address equ $0F53 ; = 3923 mem_get_address equ $0F5C ; = 3932 mem_get_size equ $0F63 ; = 3939 mem_get_address_for_index equ $0F6D ; = 3949 v_mem_get_index_for_address equ $0F72 ; = 3954 mem_get_index_for_address equ $0F75 ; = 3957 mem_assert_size equ $0F7F ; = 3967 mem_assert_free equ $0F84 ; = 3972 mas0 equ $0F90 ; = 3984 v_heap_drop_handle equ $0F93 ; = 3987 mem_heap_pop_handle equ $0F95 ; = 3989 v_heap_get_handle equ $0F9E ; = 3998 mem_heap_get_handle equ $0FA0 ; = 4000 v_stack_drop_handle equ $0FA6 ; = 4006 mem_stack_pop_handle equ $0FA8 ; = 4008 mem_stack_get_handle equ $0FB3 ; = 4019 mem_heap_new_handle equ $0FB7 ; = 4023 mem_stack_new_handle equ $0FC4 ; = 4036 mem_new_handle equ $0FCF ; = 4047 mem_new_handle_quick equ $0FDD ; = 4061 mnh1 equ $0FE8 ; = 4072 mem_stack_alloc equ $0FF8 ; = 4088 mem_heap_alloc equ $1000 ; = 4096 mem_alloc equ $1008 ; = 4104 ma2 equ $100E ; = 4110 mem_set_empty_data equ $1027 ; = 4135 ma3 equ $1027 ; = 4135 mem_stack_push_data equ $102F ; = 4143 mem_heap_push_data_no_exx equ $1035 ; = 4149 mem_heap_push_data equ $1035 ; = 4149 mem_save_data equ $103B ; = 4155 msd1 equ $103F ; = 4159 mem_restore_data equ $1049 ; = 4169 mem_dealloc equ $104D ; = 4173 mem_heap_pop_data_no_exx equ $1052 ; = 4178 mem_heap_pop_data equ $1052 ; = 4178 mem_stack_pop_data equ $1058 ; = 4184 mem_copy_data_to_de equ $105C ; = 4188 ldir_if_nz equ $105F ; = 4191 ldir equ $1062 ; = 4194 v_heap_to_stack equ $1065 ; = 4197 mem_heap_to_stack equ $1067 ; = 4199 mem_stack_push_handle equ $106A ; = 4202 v_stack_to_heap equ $107A ; = 4218 mem_stack_to_heap equ $107C ; = 4220 mem_heap_push_handle equ $107F ; = 4223 mem_stack_pick_handle equ $1091 ; = 4241 mem_is_handle equ $1097 ; = 4247 mem_is_handle_de equ $109F ; = 4255 mem_dealloc_de equ $10AE ; = 4270 v_mem_get_free equ $10B3 ; = 4275 pdexjiy equ $10B6 ; = 4278 v_mem_get_free_total equ $10BA ; = 4282 v_mem_get_address equ $10BF ; = 4287 v_mem_alloc equ $10C6 ; = 4294 xpbcjiy equ $10CC ; = 4300 v_heap_alloc equ $10D0 ; = 4304 v_stack_alloc equ $10D8 ; = 4312 v_mem_dealloc equ $10E0 ; = 4320 v_mem_new_handle equ $10E9 ; = 4329 v_mem_save_data equ $10EE ; = 4334 v_mem_restore_data equ $10F7 ; = 4343 v_heap_new_handle equ $10FE ; = 4350 v_stack_new_handle equ $1103 ; = 4355 v_stack_get_handle equ $1108 ; = 4360 v_heap_push_data equ $110D ; = 4365 pbpdjiy equ $1114 ; = 4372 v_stack_push_data equ $1118 ; = 4376 v_heap_pop_data equ $1121 ; = 4385 v_stack_pop_data equ $1127 ; = 4391 v_stack_pick_handle equ $112D ; = 4397 v_stack_peek_handle equ $1133 ; = 4403 v_stack_poke_handle equ $113A ; = 4410 v_mem_get_address_for_index equ $1147 ; = 4423 mem_cat equ $114E ; = 4430 mem_dup equ $1177 ; = 4471 mem_dup_to_stack equ $1188 ; = 4488 mem_shrink equ $1199 ; = 4505 mem_rshrink equ $119E ; = 4510 mem_shrink_quick equ $11B2 ; = 4530 mem_shrink_hl_quick equ $11B6 ; = 4534 mem_subrange equ $11CB ; = 4555 mem_sr equ $11D5 ; = 4565 msr1 equ $11DE ; = 4574 msr2 equ $11E4 ; = 4580 msr3 equ $11FA ; = 4602 msr5 equ $1204 ; = 4612 msr6 equ $1210 ; = 4624 msr7 equ $121E ; = 4638 msr_1_x equ $1225 ; = 4645 msr_x_1 equ $1225 ; = 4645 msr_0 equ $123C ; = 4668 msr_1 equ $1241 ; = 4673 mem_validate_hl_and_de equ $125C ; = 4700 mem_validate_index equ $1261 ; = 4705 vd1 equ $126C ; = 4716 mempack_end equ $1270 ; = 4720 vip_start equ $1270 ; = 4720 v_scratch equ $5B27 ; = 23335 init_vip equ $1270 ; = 4720 vip_dis equ $1271 ; = 4721 v_umax equ $1277 ; = 4727 vum1 equ $1279 ; = 4729 v_umin equ $1281 ; = 4737 vum2 equ $1283 ; = 4739 v_max equ $128B ; = 4747 v_min equ $1293 ; = 4755 v_if equ $129B ; = 4763 v_iff equ $12A2 ; = 4770 v_ifff equ $12A9 ; = 4777 skip3 equ $12AE ; = 4782 skip2 equ $12AF ; = 4783 skip1 equ $12B0 ; = 4784 v_byte equ $12B3 ; = 4787 v_peekb equ $12B7 ; = 4791 bp1 equ $12B8 ; = 4792 v_number equ $12BE ; = 4798 v_peek equ $12C7 ; = 4807 v_poke equ $12CD ; = 4813 v_pokeb equ $12D5 ; = 4821 v_over equ $12DB ; = 4827 v_pick equ $12E1 ; = 4833 v_setbit equ $12EA ; = 4842 vsb1 equ $12F7 ; = 4855 v_clrbit equ $12FB ; = 4859 vcb1 equ $1308 ; = 4872 v_jump equ $130C ; = 4876 v_bra equ $1313 ; = 4883 v_bra_if equ $131E ; = 4894 v_bra_ifnot equ $1326 ; = 4902 v_opcode equ $132E ; = 4910 v_call equ $1335 ; = 4917 v_jp_calc equ $133F ; = 4927 v_exit equ $133F ; = 4927 v_call_calc equ $1344 ; = 4932 v_penter equ $134B ; = 4939 v_preturn equ $1363 ; = 4963 v_pexit equ $1371 ; = 4977 pex1 equ $1377 ; = 4983 v_lvar equ $137B ; = 4987 v_lvar_poke equ $138A ; = 5002 v_pp equ $139C ; = 5020 v_mm equ $13A5 ; = 5029 v_pp_peek equ $13B0 ; = 5040 v_mm_peek equ $13BA ; = 5050 v_peek_pp equ $13C4 ; = 5060 v_peek_mm equ $13CF ; = 5071 v_and equ $13DA ; = 5082 v_or equ $13E3 ; = 5091 v_xor equ $13EC ; = 5100 v_tab equ $1400 ; = 5120 byte equ $0000 ; = 0 number equ $0003 ; = 3 hpeek equ $0006 ; = 6 mult equ $0009 ; = 9 div equ $000C ; = 12 rem equ $000F ; = 15 peek equ $0012 ; = 18 peekb equ $0015 ; = 21 poke equ $0018 ; = 24 pokeb equ $001B ; = 27 jump equ $001E ; = 30 if equ $0021 ; = 33 iff equ $0024 ; = 36 ifff equ $0027 ; = 39 bra equ $002A ; = 42 bra_if equ $002D ; = 45 bra_ifnot equ $0030 ; = 48 call equ $0033 ; = 51 opcode equ $0036 ; = 54 return equ $0039 ; = 57 v_return equ $1439 ; = 5177 exit equ $003C ; = 60 jp_calc equ $003C ; = 60 call_calc equ $003F ; = 63 penter equ $0042 ; = 66 preturn equ $0045 ; = 69 pexit equ $0048 ; = 72 lvar equ $004B ; = 75 lvar_poke equ $004E ; = 78 pp equ $0051 ; = 81 mm equ $0054 ; = 84 pp_peek equ $0057 ; = 87 mm_peek equ $005A ; = 90 peek_pp equ $005D ; = 93 peek_mm equ $0060 ; = 96 incr equ $0063 ; = 99 decr equ $0066 ; = 102 to_real equ $0069 ; = 105 dup equ $006B ; = 107 drop equ $006E ; = 110 nip equ $0071 ; = 113 over equ $0074 ; = 116 pick equ $0077 ; = 119 and equ $007A ; = 122 or equ $007D ; = 125 xor equ $0080 ; = 128 shl equ $0083 ; = 131 shr equ $0086 ; = 134 umax equ $0089 ; = 137 umin equ $008C ; = 140 max equ $008F ; = 143 min equ $0092 ; = 146 rnd equ $0095 ; = 149 dealloc equ $0098 ; = 152 string equ $009B ; = 155 strlen equ $009E ; = 158 catstr equ $00A1 ; = 161 leftstr equ $00A4 ; = 164 rightstr equ $00A7 ; = 167 midstr equ $00AA ; = 170 substr equ $00AD ; = 173 upperstr equ $00B0 ; = 176 lowerstr equ $00B3 ; = 179 charstr equ $00B6 ; = 182 hex2str equ $00B9 ; = 185 hex4str equ $00BC ; = 188 numstr equ $00BF ; = 191 print equ $00C2 ; = 194 printchar equ $00C5 ; = 197 printdec equ $00C8 ; = 200 printhex equ $00CB ; = 203 bit equ $00CE ; = 206 setbit equ $00D1 ; = 209 clrbit equ $00D4 ; = 212 neg equ $00D7 ; = 215 cpl equ $00D8 ; = 216 swap equ $00DA ; = 218 add equ $00DC ; = 220 sub equ $00DE ; = 222 eq equ $00E0 ; = 224 ne equ $00E2 ; = 226 gt equ $00E4 ; = 228 ge equ $00E6 ; = 230 lt equ $00E8 ; = 232 le equ $00EA ; = 234 not equ $00EC ; = 236 bool equ $00EE ; = 238 getkey equ $00F0 ; = 240 waitkey equ $00F2 ; = 242 abs equ $00F4 ; = 244 lvar_peek equ $00F6 ; = 246 v_tab_end equ $14F7 ; = 5367 v_lvar_peek_ctd equ $14F7 ; = 5367 v_abs equ $1506 ; = 5382 v_neg equ $150B ; = 5387 v_cpl equ $150C ; = 5388 v_swap equ $1515 ; = 5397 v_add equ $151A ; = 5402 v_sub equ $151F ; = 5407 vsub1 equ $1521 ; = 5409 v_ne equ $1526 ; = 5414 set1 equ $152C ; = 5420 v_eq equ $1531 ; = 5425 set0 equ $1537 ; = 5431 v_gt equ $153C ; = 5436 v_lt equ $153F ; = 5439 vlt1 equ $1545 ; = 5445 v_le equ $154B ; = 5451 v_ge equ $154E ; = 5454 vge1 equ $1554 ; = 5460 v_not equ $155A ; = 5466 v_bool equ $1560 ; = 5472 v_getkey equ $1566 ; = 5478 v_waitkey equ $156B ; = 5483 vwk1 equ $156E ; = 5486 v_bit equ $1574 ; = 5492 vb1 equ $1584 ; = 5508 up_vz_mult_quick equ $1589 ; = 5513 upvz1 equ $1592 ; = 5522 abs_de equ $159D ; = 5533 neg_de equ $15A0 ; = 5536 v_mult equ $15A8 ; = 5544 m2 equ $15BF ; = 5567 m3 equ $15C0 ; = 5568 m1 equ $15C9 ; = 5577 v_div equ $15D2 ; = 5586 vd3 equ $15D9 ; = 5593 v_rem equ $15E1 ; = 5601 vr1 equ $15E8 ; = 5608 div_hl_de equ $15EF ; = 5615 div2 equ $15F6 ; = 5622 div1 equ $1602 ; = 5634 rnd_seed equ $5B2D ; = 23341 v_rnd equ $1606 ; = 5638 rnd1 equ $160F ; = 5647 v_shl equ $1628 ; = 5672 vshl4 equ $1636 ; = 5686 vshl2 equ $163A ; = 5690 vshl3 equ $163E ; = 5694 v_shr equ $1641 ; = 5697 vshr4 equ $164F ; = 5711 vshr2 equ $1653 ; = 5715 vshr3 equ $165A ; = 5722 v_hpeek equ $165D ; = 5725 v_string equ $1667 ; = 5735 vs1 equ $166A ; = 5738 v_printchar equ $1671 ; = 5745 v_print equ $1678 ; = 5752 vp1 equ $1683 ; = 5763 vp2 equ $168B ; = 5771 v_printdec equ $168E ; = 5774 v_printhex equ $1694 ; = 5780 v_strlen equ $169A ; = 5786 v_get_strlen_and_address equ $169C ; = 5788 v_numstr equ $16A6 ; = 5798 v_hex4str equ $16BF ; = 5823 v_hex2str equ $16CD ; = 5837 vhx2 equ $16DA ; = 5850 v_charstr equ $16DE ; = 5854 make_handle equ $16EC ; = 5868 mh1 equ $16F4 ; = 5876 v_upperstr equ $1707 ; = 5895 us2 equ $170F ; = 5903 us3 equ $1719 ; = 5913 us1 equ $171A ; = 5914 v_lowerstr equ $1722 ; = 5922 ls2 equ $172A ; = 5930 ls3 equ $1734 ; = 5940 ls1 equ $1735 ; = 5941 v_catstr equ $173D ; = 5949 v_rightstr equ $176F ; = 5999 vrs1 equ $177D ; = 6013 vrs2 equ $1789 ; = 6025 v_leftstr equ $178C ; = 6028 v_midstr equ $179C ; = 6044 v_substr equ $17A2 ; = 6050 vsr1 equ $17A3 ; = 6051 v_hpushdata equ $17B6 ; = 6070 v_hpopdata equ $17C0 ; = 6080 edit_text equ $17C6 ; = 6086 ed_text equ $0005 ; = 5 ed_top equ $0004 ; = 4 ed_left equ $0003 ; = 3 ed_width equ $0002 ; = 2 ed_key equ $FFFFFFFF ; = -1 ed_pos equ $FFFFFFFE ; = -2 edtxt0 equ $17CD ; = 6093 edtxt1 equ $1809 ; = 6153 edtxt2 equ $181F ; = 6175 edtxt3 equ $182A ; = 6186 edtxt4 equ $1836 ; = 6198 vip_end equ $184A ; = 6218 ram_test equ $184A ; = 6218 cs1 equ $184F ; = 6223 cs2 equ $185F ; = 6239 cs3 equ $186A ; = 6250 cs5 equ $1877 ; = 6263 ram_broken_1 equ $1881 ; = 6273 ram_broken_2 equ $1887 ; = 6279 init_errors equ $188D ; = 6285 errno equ $5B30 ; = 23344 error_msg_handle equ $5B31 ; = 23345 error_handler equ $5B33 ; = 23347 noerror equ $0000 ; = 0 error_message equ $0001 ; = 1 error_oomem equ $0002 ; = 2 error_notester equ $0003 ; = 3 error_messages equ $1893 ; = 6291 abort_oomem equ $18B7 ; = 6327 abort equ $18B9 ; = 6329 set_error_handler equ $18C0 ; = 6336 get_error_handler equ $18C4 ; = 6340 set_error_message equ $18C8 ; = 6344 sem1 equ $18D2 ; = 6354 print_error_message equ $18E5 ; = 6373 pem1 equ $18FD ; = 6397 pem2 equ $1902 ; = 6402 up_show_error equ $1908 ; = 6408 oomem_handler equ $1928 ; = 6440 oo_oo equ $1939 ; = 6457 msg_presskey equ $199C ; = 6556 msg_ok equ $19AC ; = 6572 msg_yes equ $19B1 ; = 6577 msg_no equ $19B7 ; = 6583 msg_cancel equ $19BC ; = 6588 msg_enter equ $19C5 ; = 6597 open_alert equ $19CD ; = 6605 oa1 equ $1A0A ; = 6666 oa2 equ $1A10 ; = 6672 alert_save_pixels equ $1A2A ; = 6698 alert_set_main_text equ $1A3A ; = 6714 absmt1 equ $1A48 ; = 6728 absmt5 equ $1A4F ; = 6735 absmt2 equ $1A5A ; = 6746 absmt4 equ $1A5F ; = 6751 absmt3 equ $1A73 ; = 6771 up_print_some_text equ $1A7C ; = 6780 alert_add_button equ $1A94 ; = 6804 close_alert equ $1ACC ; = 6860 ca3 equ $1ACE ; = 6862 ca_attr equ $1ADD ; = 6877 keycode_illegal equ $0000 ; = 0 keycode_cshift equ $0000 ; = 0 keycode_sshift equ $0000 ; = 0 keycode_edit equ $0001 ; = 1 keycode_capslock equ $0002 ; = 2 keycode_video equ $0003 ; = 3 keycode_rvideo equ $0004 ; = 4 keycode_left equ $0005 ; = 5 keycode_down equ $0006 ; = 6 keycode_up equ $0007 ; = 7 keycode_right equ $0008 ; = 8 keycode_graphics equ $0009 ; = 9 keycode_delete equ $000A ; = 10 keycode_cshift_space equ $000B ; = 11 keycode_cshift_sshift equ $000C ; = 12 keycode_return equ $000D ; = 13 poundsterling equ $0060 ; = 96 keys equ $1AE2 ; = 6882 skeys equ $1B0A ; = 6922 ckeys equ $1B32 ; = 6962 keys_end equ $1B5A ; = 7002 init_keyboard equ $1B5A ; = 7002 wait_newkey equ $1B5B ; = 7003 wait_inkey equ $1B5E ; = 7006 flush_inkey equ $1B65 ; = 7013 get_inkey equ $1B75 ; = 7029 kfs_x equ $1B8F ; = 7055 key_inkey equ $5B35 ; = 23349 key_oldkey equ $5B37 ; = 23351 nokey equ $0000 ; = 0 cshift_scancode equ $0001 ; = 1 sshift_scancode equ $0025 ; = 37 sshift_mask equ $0040 ; = 64 cshift_mask equ $0080 ; = 128 sshift_bit equ $0006 ; = 6 cshift_bit equ $0007 ; = 7 key_timer equ $5B38 ; = 23352 key_guardtime equ $0002 ; = 2 key_startdelay equ $000A ; = 10 key_repeatdelay equ $0004 ; = 4 irpt_scan_keyboard equ $1B98 ; = 7064 isk0 equ $1BA8 ; = 7080 isk01 equ $1BAC ; = 7084 isk001 equ $1BAE ; = 7086 isk4 equ $1BBB ; = 7099 isk3 equ $1BC0 ; = 7104 isk5 equ $1BCD ; = 7117 isk7 equ $1BDB ; = 7131 isk61 equ $1BE1 ; = 7137 isk8 equ $1BEA ; = 7146 isk10 equ $1BFE ; = 7166 isk6 equ $1C01 ; = 7169 isk11 equ $1C07 ; = 7175 isk111 equ $1C19 ; = 7193 isk112 equ $1C2A ; = 7210 isk13 equ $1C30 ; = 7216 isk14 equ $1C34 ; = 7220 io_pins equ $5B39 ; = 23353 io_flags equ $5B3A ; = 23354 io_flag_irpt equ $0007 ; = 7 io_bits_table equ $5B3B ; = 23355 io_bits_l equ $5B3B ; = 23355 io_bits_A8 equ $5B3B ; = 23355 io_bits_A9 equ $5B3F ; = 23359 io_bits_A10 equ $5B43 ; = 23363 io_bits_r equ $5B47 ; = 23367 io_bits_A11 equ $5B47 ; = 23367 io_bits_A12 equ $5B4B ; = 23371 io_bits_A13 equ $5B4F ; = 23375 io_offset_out equ $0000 ; = 0 io_offset_in equ $0002 ; = 2 io_offset_new equ $0000 ; = 0 io_offset_old equ $0001 ; = 1 io_bits_data_size equ $0004 ; = 4 io_bits_table_size equ $0018 ; = 24 ic_middle equ $0018 ; = 24 ic_col_lout equ $0010 ; = 16 ic_col_ltype equ $0011 ; = 17 ic_col_lin equ $0013 ; = 19 ic_col_lname equ $0014 ; = 20 ic_col_rname equ $0018 ; = 24 ic_col_rin equ $001C ; = 28 ic_col_rtype equ $001D ; = 29 ic_col_rout equ $001F ; = 31 ic_pin_name_sz equ $0006 ; = 6 ic_pin_name equ $5B53 ; = 23379 ic_pin_type equ $5C73 ; = 23667 ic_pin_type_unknown equ $0000 ; = 0 ic_pin_type_gnd equ $0001 ; = 1 ic_pin_type_vcc equ $0002 ; = 2 ic_pin_type_input equ $0003 ; = 3 ic_pin_type_output equ $0004 ; = 4 ic_pin_type_io equ $0005 ; = 5 ic_pin_type_oK equ $0006 ; = 6 ic_pin_type_3state equ $0007 ; = 7 ic_pin_type_nc equ $0008 ; = 8 get_pin_type equ $1C3E ; = 7230 set_pin_type equ $1C45 ; = 7237 ic_set_pin_type_for_current_pin equ $1C4C ; = 7244 ic_draw_all_pin_types equ $1C58 ; = 7256 icdap1 equ $1C5A ; = 7258 ic_draw_pin_type_for_current_pin equ $1C63 ; = 7267 ic_draw_pin_type equ $1C66 ; = 7270 icdp1 equ $1C78 ; = 7288 ic_pin_type_text_r equ $1CA1 ; = 7329 icptr1 equ $1CA9 ; = 7337 icptr2 equ $1CAB ; = 7339 icptr3 equ $1CAD ; = 7341 icptr4 equ $1CAF ; = 7343 icptr5 equ $1CB1 ; = 7345 icptr6 equ $1CB3 ; = 7347 icptr7 equ $1CB6 ; = 7350 icptr8 equ $1CB9 ; = 7353 ic_pin_type_text_l equ $1CBC ; = 7356 icptl1 equ $1CC4 ; = 7364 icptl2 equ $1CC8 ; = 7368 icptl3 equ $1CCC ; = 7372 icptl4 equ $1CD0 ; = 7376 icptl5 equ $1CD4 ; = 7380 icptl6 equ $1CD8 ; = 7384 icptl7 equ $1CDD ; = 7389 icptl8 equ $1CE2 ; = 7394 calc_hl_mask_a_for_pin equ $1CE7 ; = 7399 calc_attr_hl_for_name equ $1D01 ; = 7425 calc_attr_hl_for_type equ $1D0B ; = 7435 calc_attr_hl_for_obit equ $1D15 ; = 7445 ca2 equ $1D1D ; = 7453 ca1 equ $1D20 ; = 7456 calc_pin_from_hilight equ $1D24 ; = 7460 calc_pin_from_rowcol equ $1D28 ; = 7464 test_col_c_is_obit equ $1D31 ; = 7473 test_col_c_is_name equ $1D38 ; = 7480 test_col_c_is_type equ $1D3F ; = 7487 ic_hilight_row_col equ $5CA3 ; = 23715 ic_hilight_col equ $5CA3 ; = 23715 ic_hilight_row equ $5CA4 ; = 23716 ic_hilight_size_attr equ $5CA5 ; = 23717 ic_hilight_size equ $5CA5 ; = 23717 ic_hilight_attr equ $5CA6 ; = 23718 ic_clear_hilight equ $1D46 ; = 7494 icca1 equ $1D59 ; = 7513 icca3 equ $1D5E ; = 7518 ic_set_hilight equ $1D60 ; = 7520 icsh1 equ $1D6B ; = 7531 ic_size_tab equ $1D7A ; = 7546 ic_col0_tab equ $1D8A ; = 7562 ic_next_tab equ $1D9A ; = 7578 ic_validate_hilight equ $1DAA ; = 7594 ic_get_size_for_col equ $1DB6 ; = 7606 ic_validate_col equ $1DC1 ; = 7617 ic_validate_row equ $1DCE ; = 7630 ic_move_hilight_down equ $1DE1 ; = 7649 ic_move_hilight equ $1DE3 ; = 7651 ic_up equ $1E0C ; = 7692 ic_down equ $1E0E ; = 7694 ic_left equ $1E10 ; = 7696 ic_right equ $1E12 ; = 7698 init_pin_display equ $1E1D ; = 7709 stop_pin_display equ $1E1D ; = 7709 start_pin_display equ $1E25 ; = 7717 resume_pin_display equ $1E2A ; = 7722 ic_force_redraw equ $1E31 ; = 7729 icfr1 equ $1E38 ; = 7736 ic_detect_size equ $1E45 ; = 7749 icds1 equ $1E4B ; = 7755 icds2 equ $1E59 ; = 7769 ic_get_pin equ $1E62 ; = 7778 ic_set_pin_to_cy equ $1E6E ; = 7790 ic_reset_current_pin equ $1E70 ; = 7792 ic_reset_pin equ $1E77 ; = 7799 ics1 equ $1E7D ; = 7805 ics2 equ $1E7E ; = 7806 ic_set_current_pin equ $1E82 ; = 7810 ic_set_pin equ $1E89 ; = 7817 ics3 equ $1E8A ; = 7818 ic_toggle_current_pin equ $1E90 ; = 7824 ic_toggle_pin equ $1E97 ; = 7831 ic_trigger_current_pin equ $1E9E ; = 7838 ic_trigger_pin equ $1EA5 ; = 7845 ic_calc_ahlbc_for_pin_a_no_exx equ $1EAF ; = 7855 ic_calc_ahlbc_for_pin_a equ $1EAF ; = 7855 io_sync_iobits equ $1ECD ; = 7885 io_sync_ibits equ $1ED0 ; = 7888 isi1 equ $1EDA ; = 7898 io_sync_obits equ $1EE4 ; = 7908 iso1 equ $1EEE ; = 7918 ic_test_tester_present equ $1EF8 ; = 7928 iso3 equ $1F09 ; = 7945 iso4 equ $1F12 ; = 7954 iso5 equ $1F25 ; = 7973 iso55 equ $1F28 ; = 7976 msg_tester_broken equ $1F4A ; = 8010 msg_tester_broken_group equ $000A ; = 10 msg_tester_broken_lo equ $001C ; = 28 msg_tester_broken_hi equ $001B ; = 27 ic_switch_vcc_on equ $1F69 ; = 8041 ic_switch_vcc_off equ $1F71 ; = 8049 iso2 equ $1F80 ; = 8064 ic_render_pin_no_exx equ $1F88 ; = 8072 ic_render_pin equ $1F88 ; = 8072 icrp1 equ $1F96 ; = 8086 char_0 equ $1FA0 ; = 8096 char_1 equ $1FA7 ; = 8103 ic_render_8_pins_left_no_exx equ $1FAF ; = 8111 ic_render_8_pins_left equ $1FAF ; = 8111 icr2 equ $1FC0 ; = 8128 icr1 equ $1FC3 ; = 8131 ic_render_8_pins_right_no_exx equ $1FCE ; = 8142 ic_render_8_pins_right equ $1FCE ; = 8142 icr4 equ $1FDE ; = 8158 irpt_pin_display equ $1FEE ; = 8174 ic_update_all_pins_no_exx equ $1FF4 ; = 8180 ic_update_all_pins equ $1FF4 ; = 8180 icr5 equ $2002 ; = 8194 timer_cell equ $5CA7 ; = 23719 init_timer equ $2031 ; = 8241 irpt_timer equ $2032 ; = 8242 calc_strlen equ $203D ; = 8253 sl1 equ $2040 ; = 8256 vzdecstr equ $2049 ; = 8265 decstr equ $2058 ; = 8280 decstr_max3digits equ $206A ; = 8298 decstr5 equ $207E ; = 8318 decstr4 equ $2084 ; = 8324 decstr3 equ $208A ; = 8330 decstr2 equ $2090 ; = 8336 decstr1 equ $2096 ; = 8342 ds equ $2099 ; = 8345 ds1 equ $209C ; = 8348 hexstr4 equ $20A5 ; = 8357 hexstr2 equ $20AC ; = 8364 hexstr1hi equ $20B3 ; = 8371 hexstr1 equ $20B7 ; = 8375 hs1 equ $20C1 ; = 8385 binstr16 equ $20C4 ; = 8388 binstr8 equ $20CB ; = 8395 bs0 equ $20CE ; = 8398 bs1 equ $20CF ; = 8399 binstr4 equ $20DA ; = 8410 deref_hl equ $20DF ; = 8415 calc_hex_char_hi equ $20E4 ; = 8420 calc_hex_char equ $20E8 ; = 8424 mult_bc equ $20F2 ; = 8434 mult_ac equ $20F3 ; = 8435 mu2 equ $20FB ; = 8443 mu1 equ $20FF ; = 8447 calc_rbmask equ $2107 ; = 8455 calc_bmask equ $2108 ; = 8456 crfb2 equ $210C ; = 8460 calc_rnmask equ $2113 ; = 8467 calc_nmask equ $2114 ; = 8468 calc_lmask equ $211A ; = 8474 calc_rmask equ $2122 ; = 8482 crfb1 equ $212A ; = 8490 masks equ $212E ; = 8494 bmasks equ $212E ; = 8494 nmasks equ $2136 ; = 8502 lmasks equ $213E ; = 8510 rmasks equ $2146 ; = 8518 vip_test equ $214E ; = 8526 vt1 equ $216E ; = 8558 vt2 equ $217F ; = 8575 vt3 equ $2190 ; = 8592 vt24 equ $21A0 ; = 8608 vt4 equ $21B1 ; = 8625 vt5 equ $21C1 ; = 8641 vt6 equ $21D1 ; = 8657 vt7 equ $21E2 ; = 8674 vt8 equ $21F3 ; = 8691 vt9 equ $2204 ; = 8708 vt10 equ $2214 ; = 8724 vt11 equ $2224 ; = 8740 vt12 equ $2234 ; = 8756 vt13 equ $2246 ; = 8774 vt14 equ $2258 ; = 8792 vt15 equ $2268 ; = 8808 vt16 equ $227F ; = 8831 vt17 equ $2295 ; = 8853 vt18 equ $22B0 ; = 8880 vt19 equ $22CC ; = 8908 vt20 equ $22E8 ; = 8936 vt21 equ $2301 ; = 8961 vt22 equ $231B ; = 8987 vt23 equ $233A ; = 9018 vt25 equ $2357 ; = 9047 vt26 equ $236D ; = 9069 vt27 equ $2385 ; = 9093 vt28 equ $239C ; = 9116 vt29 equ $23B3 ; = 9139 sys_info_attr equ $0068 ; = 104 sys_info_h_attr equ $0027 ; = 39 system_info equ $23BE ; = 9150 press_any_key equ $2526 ; = 9510 v_calc_min_stack_free equ $253C ; = 9532 cms1 equ $2544 ; = 9540 print_obit_menu equ $254D ; = 9549 print_type_menu equ $2599 ; = 9625 print_name_menu equ $260D ; = 9741 free_test_menu equ $267F ; = 9855 ft1 equ $2745 ; = 10053 set_pintype_input equ $27B2 ; = 10162 set_pintype_output equ $27B6 ; = 10166 set_pintype_3state equ $27BA ; = 10170 set_pintype_oK equ $27BE ; = 10174 set_pintype_io equ $27C2 ; = 10178 set_pintype_nc equ $27C6 ; = 10182 set_pintype_vcc equ $27CA ; = 10186 set_pintype_gnd equ $27CE ; = 10190 set_pintype_unknown equ $27D2 ; = 10194 spt1 equ $27D4 ; = 10196 edit_pin_name equ $27DA ; = 10202 set_pin_count equ $27DA ; = 10202 edit_pin_info equ $27DA ; = 10202 fetch_ic_info equ $27DA ; = 10202 store_ic_info equ $27DA ; = 10202 calc_checksum equ $27DA ; = 10202 code_end equ $27DB ; = 10203 data_end equ $5CAA ; = 23722