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: FD212F12 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: CDA31E call irpt_timer 003F: CD091A call irpt_scan_keyboard 0042: CD5F1E 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: C3BB16 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: 21A85C ld hl,data_end ; hl = start of available ram 0084: CD810E call mem_init ; [hl .. ram .. [de 0087: CDFE16 call init_errors ; set oomem handler 008A: CDC603 call init_print ; Print-Routinen 008D: CD2E12 call init_vip 0090: 0090: ; Interrupts: 0090: 0090: CDA21E call init_timer ; Timer 0093: CDCB19 call init_keyboard ; Scan Keyboard 0096: CD8E1C call init_pin_display ; IC-Grafik 0099: ED46 im 0 ; => RST 7 009B: FB ei ; => Interrupt := ON 009C: 009C: ; Systemstart 009C: 009C: CD691D 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: CDCF19 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: CD8E1C 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: CD5617 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: C424 defw free_test_menu 01AF: 35 defb '5' 01B0: 1022 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: BF1F defw vip_test 01BB: 00 defb 0 01BC: 9901 defw mm1 01BE: 18D9 jr mm1 01C0: 01C0: 01C0: ram_test_menu: 01C0: CD8E1C 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: CD5617 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: CD8E1C 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: CD5617 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: CD8E1C 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: CD5617 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: CD0110 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: CD1E10 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: CDC91E 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: CDBA1E 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: CD161F 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: CD1D1F 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: CD3C1F 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: CD4B1F 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 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: 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: CDCC19 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: 545D 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: 545D 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: 5059 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: 424B 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: CD631F 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: 444D ld bc,hl ; bc = size 0CDF: CDD20F 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: CD631F 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: 444D ld bc,hl ; bc = size 0D10: CDD20F 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: CD720F call mem_heap_pop_handle ; hl -> handle 0D4B: CD4D0F 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: CD720F call mem_heap_pop_handle ; hl -> handle 0D85: CD4D0F 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: 545D 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_end data 2 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: 0E77: ; mem_alloc bc:size -- hl:handleptr de:dataptr bc:size z|nz 0E77: ; mem_realloc hl:handleptr -- hl:handleptr de->data bc=size 0E77: ; mem_dealloc hl:handleptr -- 0E77: ; mem_new_handle -- hl:handleptr 0E77: 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_peek_handle [handle] -- [handle] hl:handleptr 0E77: ; mem_heap_pick_handle de:index [handle_n..handle1] -- hl:handle_i_ptr 0E77: ; mem_heap_push_data hl:dataptr bc:size -- hl:handleptr 0E77: ; mem_heap_pop_data de:destptr -- 0E77: ; mem_heap_swap_handles {str1} {str2} -- {str2} {str1} 0E77: 0E77: ; ========================================================================= 0E77: ; Utilities: 0E77: 0E77: ; mem_copy_data_to_de 0E77: ; ldir_if_nz 0E77: ; ldir 0E77: ; mem_assert_size 0E77: ; mem_assert_free 0E77: 0E77: 0E77: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0E77: ; Virtual Machine Opcodes 0E77: 0E77: v_mem_get_free_total: ; -- 0E77: CDA20E call mem_compact 0E7A: 0E7A: v_mem_get_free: ; -- 0E7A: CD310F call mem_get_free 0E7D: D5 push de 0E7E: EB ex hl,de 0E7F: FDE9 jp (iy) 0E81: 0E81: ; v_mem_compact: ; -- 0E81: ; push iy 0E81: ; jp mem_compact 0E81: 0E81: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0E81: 0E81: 0E81: 0E81: ; -------------------------------------------------------- 0E81: ; Initialize Memory Handler 0E81: ; 0E81: ; in: hl -> first usable byte 0E81: ; de -> behind last usable byte 0E81: ; out: -- 0E81: ; mod: af, bc, de, hl 0E81: 0E81: mem_init: 0E81: 22175B ld (mem_start),hl ; mem start = data start 0E84: 22195B ld (mem_free_start),hl ; free start = data end 0E87: 0E87: EB ex hl,de 0E88: CB85 res 0,l ; Handles auf gerade Adressen ausrichten 0E8A: 0E8A: 22235B ld (mem_end),hl ; mem end = stack end 0E8D: 25 dec h ; 256 bytes for stack 0E8E: 0E8E: 22215B ld (mem_heap_ptr),hl ; heap := empty 0E91: 221F5B ld (mem_handles_end),hl ; heap start = handles end 0E94: 221B5B ld (mem_handles_start),hl ; free end = handles start 0E97: 221D5B ld (mem_last_handle),hl 0E9A: 0E9A: 010000 ld bc,0 ; minimalen Speicherblock im Speicher anlegen. 0E9D: C3DA0F jp mem_alloc ; => es ist immer ein Block in der Verwaltung. 0EA0: ; -> Verwendung als Stopper zB. in mem_compact. 0EA0: 0EA0: 0EA0: 0EA0: ; -------------------------------------------------------- 0EA0: ; Garbage Collection 0EA0: ; 0EA0: ; in: -- 0EA0: ; out: -- 0EA0: ; mod: -- 0EA0: 0EA0: v_mem_compact: 0EA0: FDE5 push iy ; return address 0EA2: 0EA2: mem_compact_no_exx: 0EA2: mem_compact: 0EA2: D7 rst save_registers 0EA3: F5 push af 0EA4: 0EA4: ; ----- Handles: ----- 0EA4: 0EA4: 3E00 ld a,black ; visual effect: border 0EA6: D3FE out ($fe),a 0EA8: 0EA8: ; handle-allocation-pointer zurücksetzen: 0EA8: 2A1F5B ld hl,(mem_handles_end) 0EAB: 221D5B ld (mem_last_handle),hl 0EAE: 0EAE: ; freie Handles am Anfang des Handles-Bereiches entfernen: 0EAE: EB ex hl,de ; de = mem_handles_end 0EAF: 2A1B5B ld hl,(mem_handles_start) 0EB2: 97 sub a 0EB3: 2B dec hl ; -> before_first_handle.hi 0EB4: 0EB4: 23 mc0 inc hl 0EB5: 23 inc hl 0EB6: BE cp (hl) ; handle.hi 0EB7: 28FB jr z,mc0 ; der ist auch noch frei 0EB9: 0EB9: 2B dec hl ; handle.lo 0EBA: 221B5B ld (mem_handles_start),hl ; hl -> 1st used handle 0EBD: 0EBD: ; ----- Datenblocks ----- 0EBD: 0EBD: 3E01 ld a,blue ; visual effect: border 0EBF: D3FE out ($fe),a 0EC1: 0EC1: ; 1. Schleife über alle handles: 0EC1: ; In allen belegten data.size wird ein rptr auf das handle 0EC1: ; und in das Handle die Länge aus data.size eingetragen. 0EC1: 0EC1: ; hl -> current handle ist da schon drin 0EC1: ; ld iy,(mem_handles_end) global handles und heap 0EC1: ; call mem_compact_loop1 werden in einem Durchlauf gemacht, 0EC1: ; weil sie direkt aneinander 0EC1: ; ld hl,(mem_heap_start) anschließen 0EC1: FD2A215B ld iy,(mem_heap_ptr) 0EC5: CDFA0E call mem_compact_loop1 0EC8: 0EC8: ; 2. Schleife über alle Datenblöcke: 0EC8: ; Unbelegte Blöcke werden übersprungen, 0EC8: ; Belegte Blöcke werden bündig nach vorne angerückt, 0EC8: ; data.size wird restauriert und die Pointer in allen Handles aktualisiert. 0EC8: 0EC8: 3E02 ld a,red ; visual effect: border 0ECA: D3FE out ($fe),a 0ECC: 0ECC: 2A175B ld hl,(mem_data_start) ; hl -> old data 0ECF: 545D ld de,hl ; de -> new data 0ED1: FD2A195B ld iy,(mem_data_end) ; for loop end test 0ED5: CD230F call mem_compact_loop2 0ED8: 0ED8: ; update sysvar & exit 0ED8: ED53195B ld (mem_data_end),de 0EDC: 0EDC: CD7F0B call scr_restore_border ; clear visual effect, restore old border color 0EDF: F1 pop af 0EE0: C9 ret 0EE1: 0EE1: 0EE1: ; mem_compact_loop1: 0EE1: ; in der ersten Schleife über alle Handles wird in allen 0EE1: ; belegten data.size ein rptr auf das handle und in das handle 0EE1: ; die länge aus data.size eingetragen. 0EE1: ; Wenn mehrere Handles auf den gleichen Datenblock zeigen, 0EE1: ; wird eine Kette data.size->handle1->handle2->handle_n=data_size aufgebaut. 0EE1: ; 0EE1: ; in: hl -> first handle 0EE1: ; iy -> behind last handle 0EE1: ; out: hl = iy 0EE1: ; mod: af,bc,de,hl 0EE1: 0EE1: ; Lese Datenadresse aus dem Handle: 0EE1: 5E mc1 ld e,(hl) 0EE2: 23 inc hl 0EE3: 7E ld a,(hl) ; de -> data.size 0EE4: 23 inc hl ; hl -> next handle 0EE5: ; handle frei? -> loop 0EE5: ; freies handle => end-of-loop test nicht nötig: 0EE5: ; mem_handle_start..mem_handle_end: finales handle aus mem_init exisitiert immer 0EE5: ; stack und heap: Dürfen keine freigegebenen Handles enthalten. 0EE5: ; (wenn doch, dann muss das hier geändert werden.) 0EE5: A7 and a 0EE6: 28F9 jr z,mc1 0EE8: FE0E cp mem_empty_data>>8 0EEA: 280E jr z,mc1e ; mem_empty_data liegt nicht im freien Speicher => nicht relozieren => skip 0EEC: 57 ld d,a 0EED: 2B dec hl 0EEE: 2B dec hl ; hl -> handle 0EEF: 0EEF: ; Der aus dem Handle ausgelesene Wert muss jetzt folgendes sein: 0EEF: ; ptr -> data.size 0EEF: ; 0EEF: ; Der Wert in data.size kann folgendes sein: 0EEF: ; Block size => handle.ptr = data.size; data.size -> handle 0EEF: ; ptr -> other handle => handle.ptr -> other_handle; data.size -> handle 0EEF: 0EEF: ; get BC = data size or ptr to other handle from DE -> data.size 0EEF: ; store handle HL in data.size 0EEF: EB ex hl,de ; hl -> data.size.lo; de -> handle 0EF0: 4E ld c,(hl) 0EF1: 73 ld (hl),e 0EF2: 23 inc hl ; hl -> data.size.hi 0EF3: 46 ld b,(hl) ; bc = size or ptr to other handle 0EF4: 72 ld (hl),d 0EF5: EB ex hl,de ; hl -> handle 0EF6: 0EF6: ; speichere im Handle die Länge oder den Zeiger auf ein anderes Handle aus BC 0EF6: 71 ld (hl),c 0EF7: 23 inc hl ; hl -> handle.hi 0EF8: 70 ld (hl),b 0EF9: 23 inc hl ; hl -> next handle 0EFA: 0EFA: mem_compact_loop1: 0EFA: 0EFA: ; loop end test: 0EFA: FD7D mc1e ld a,yl ; mem_handles_end.lo 0EFC: BD cp l 0EFD: 20E2 jr nz,mc1 0EFF: FD7C ld a,yh ; mem_handles_end.hi 0F01: BC cp h 0F02: 20DD jr nz,mc1 0F04: C9 ret 0F05: 0F05: 0F05: ; mem_compact_loop2: 0F05: ; in der zweiten schleife über alle Datenblöcke werden freigegebene Blöcke, 0F05: ; erkennbar daran, dass in ihrem size-Feld kein rptr eingetragen wurde, 0F05: ; übersprungen. Alle benutzten Blöcke, erkennbar daran, dass sie jetzt im size-Feld 0F05: ; einen rptr auf ein Handle enthalten, erkennbar daran, dass die Blockgröße größer als 0F05: ; mem_max_size ist, werden bündig nach vorne geschoben, in das size-Feld 0F05: ; wieder die Länge eingetragen und in das Handle wieder ein Zeiger auf die neue 0F05: ; Position des Blocks. Zeigen mehrere Handles auf den Block, bilden sie eine verkettete 0F05: ; Liste: data.size->handle1->handle2->handle_n=data_size und werden alle korrigiert. 0F05: ; 0F05: ; in: hl -> old data 0F05: ; de -> new data 0F05: ; iy -> behind data end 0F05: ; out: hl -> old data end = iy 0F05: ; de -> new data end 0F05: ; mod: af,bc,de,hl 0F05: 0F05: ; get data.size: 0F05: 4E mc2 ld c,(hl) 0F06: 23 inc hl 0F07: 46 ld b,(hl) ; bc = size or ptr -> handle 0F08: 23 inc hl ; hl -> old_data.data 0F09: 0F09: ; data.size = size? => free block => skip 0F09: 3E5F ld a,mem_max_hi-1 0F0B: B8 cp b 0F0C: 3014 jr nc,mc2ee ; => bc = size => free block => skip & loop 0F0E: 0F0E: ; block is in use: 0F0E: ; bc -> handle 0F0E: ; hl->old data.data 0F0E: ; de->new data.size 0F0E: 0F0E: ; read bc = size (or ptr to other handle) from handle 0F0E: ; write de = new data address into handle 0F0E: ; if the read size is > mem_max_size, then this is a link to another handle. 0F0E: ; Then do same with the other handle. 0F0E: E5 push hl ; sp: -> old_data.data 0F0F: 0F0F: 6069 mc3 ld hl,bc ; hl -> handle.lo 0F11: 4E ld c,(hl) 0F12: 73 ld (hl),e 0F13: 23 inc hl ; hl -> handle.hi 0F14: 46 ld b,(hl) ; bc = value read from handle 0F15: 72 ld (hl),d ; store de -> new data.size in handle 0F16: B8 cp b ; mem_max_hi-1 - b 0F17: 38F6 jr c,mc3 ; bc -> other handle 0F19: ; das ausgelesene BC ist jetzt wirklich data_size. 0F19: E1 pop hl ; hl -> old_data.data 0F1A: 0F1A: ; write bc = size to new data.size 0F1A: EB ex hl,de ; hl -> new data.size; de->old data.data 0F1B: 71 ld (hl),c 0F1C: 23 inc hl 0F1D: 70 ld (hl),b ; new_data.size := size 0F1E: 23 inc hl ; hl -> new_data.data 0F1F: EB ex hl,de ; de -> new_data.data; hl -> old_data.data; bc = size > 0 0F20: 0F20: ; note: bc = size > 0 is guaranteed because we do not store 0-byte chunks 0F20: ; note: we also ldir the first chunks up to the first free chunk, though this is a nop. 0F20: ; but test for hl==de and adding bc to hl and de instead of ldir adds too much 0F20: ; overhead to each loop. 0F20: EDB0 ldir ; bc=0; de->new_data.end; hl->old_data.end 0F22: ;jr mc2e ((add hl,bc=0 is a nop)) 0F22: 0F22: 09 mc2ee add hl,bc ; skip old data for free block 0F23: 0F23: mem_compact_loop2: 0F23: 0F23: ; loop end test ; hl -> old data 0F23: ; de -> new data 0F23: FD7C mc2e ld a,yh ; mem_data_end.hi 0F25: BC cp h 0F26: 20DD jr nz,mc2 0F28: FD7D ld a,yl ; mem_data_end.lo 0F2A: BD cp l 0F2B: 20D8 jr nz,mc2 0F2D: C9 ret 0F2E: 0F2E: 0F2E: 0F2E: ; -------------------------------------------------------- 0F2E: ; Get total amount of ultimately available memory 0F2E: ; runs the garbage collection and 0F2E: ; then returns the total amount of free ram. 0F2E: ; note: there may be up to 4 bytes more availabe than returned. 0F2E: ; 0F2E: ; in: -- 0F2E: ; out: hl = free memory size 0F2E: ; nc & nz: hl>0 0F2E: ; nc & z: hl=0; 0-byte request will work. 0F2E: ; cy & z: hl=0; 0-byte request will fail. 0F2E: ; mod: af, hl 0F2E: 0F2E: mem_get_free_total_no_exx: 0F2E: mem_get_free_total: 0F2E: CDA20E call mem_compact_no_exx 0F31: ;jr mem_get_free 0F31: 0F31: 0F31: 0F31: ; -------------------------------------------------------- 0F31: ; Get amount of immediately available memory 0F31: ; which will not trigger the garbage collection. 0F31: ; note: there may be up to 4 bytes more availabe than returned. 0F31: ; 0F31: ; in: -- 0F31: ; out: hl = immediately available memory size 0F31: ; nc & nz: hl>0 0F31: ; nc & z: hl=0; 0 bytes immediately available. 0F31: ; cy & z: hl=0; even a 0-byte request will trigger mem_compact. 0F31: ; mod: af, hl 0F31: 0F31: mem_get_free_no_exx: 0F31: mem_get_free: 0F31: D5 push de 0F32: 0F32: 2A1B5B ld hl,(mem_free_end) 0F35: ED5B195B ld de,(mem_free_start) 0F39: 0F39: 2B dec hl ; -2 for data.size 0F3A: 2B dec hl 0F3B: 2B dec hl ; -2 for handle 0F3C: 37 scf 0F3D: 0F3D: ED52 sbc hl,de 0F3F: 0F3F: D1 pop de 0F40: D0 ret nc ; z or nz 0F41: 0F41: ; less than 0 bytes free: 0F41: 24 inc h ; h = 0 & z 0F42: 6C ld l,h ; hl = 0 0F43: C9 ret ; z & cy 0F44: 0F44: 0F44: 0F44: ; -------------------------------------------------------- 0F44: ; Get data address and size for handle. 0F44: ; 0F44: ; in: hl -> handle 0F44: ; out: hl -> data 0F44: ; bc = size 0F44: ; mod: a, bc, hl 0F44: 0F44: mem_get_size_and_address: 0F44: 7E ld a,(hl) 0F45: 23 inc hl 0F46: 66 ld h,(hl) 0F47: 6F ld l,a ; hl -> data.size 0F48: 4E ld c,(hl) 0F49: 23 inc hl 0F4A: 46 ld b,(hl) ; bc = size 0F4B: 23 inc hl ; hl -> data.data 0F4C: C9 ret 0F4D: 0F4D: 0F4D: ; -------------------------------------------------------- 0F4D: ; Get data address for handle. 0F4D: ; 0F4D: ; in: hl -> handle 0F4D: ; out: hl -> data 0F4D: ; mod: a, hl 0F4D: 0F4D: mem_get_address_no_exx: 0F4D: mem_get_address: 0F4D: 7E ld a,(hl) 0F4E: 23 inc hl 0F4F: 66 ld h,(hl) 0F50: 6F ld l,a 0F51: 23 inc hl 0F52: 23 inc hl 0F53: C9 ret 0F54: 0F54: 0F54: ; -------------------------------------------------------- 0F54: ; Get data size for handle. 0F54: ; 0F54: ; in: hl -> handle 0F54: ; out: bc = size 0F54: ; mod: a, bc 0F54: 0F54: mem_get_size_no_exx: 0F54: mem_get_size: 0F54: E5 push hl 0F55: 7E ld a,(hl) 0F56: 23 inc hl 0F57: 66 ld h,(hl) 0F58: 6F ld l,a ; hl -> data.size 0F59: 4E ld c,(hl) 0F5A: 23 inc hl 0F5B: 46 ld b,(hl) 0F5C: E1 pop hl ; handle 0F5D: C9 ret 0F5E: 0F5E: 0F5E: 0F5E: ; -------------------------------------------------------- 0F5E: ; UP: Test whether BC bytes are available. 0F5E: ; runs the garbage collection if required. 0F5E: ; aborts if not available. 0F5E: ; 0F5E: ; mem_assert_free: only checks for enough free memory 0F5E: ; mem_assert_size: also checks for valid requested size 0F5E: ; 0F5E: ; in: bc = requested size 0F5E: ; out -- 0F5E: ; mod: af, hl 0F5E: 0F5E: mem_assert_size_no_exx: 0F5E: mem_assert_size: 0F5E: 3E5F ld a,mem_max_hi-1 0F60: B8 cp b 0F61: 380C jr c,mas0 ; bc > mem_max => error => abort 0F63: 0F63: mem_assert_free_no_exx: 0F63: mem_assert_free: 0F63: CD310F call mem_get_free_no_exx ; -> nc/cy, z/nz, hl >= 0 0F66: ED42 sbc hl,bc ; -> nc/cy 0F68: D0 ret nc ; passt ohne garbage collection 0F69: 0F69: CD2E0F call mem_get_free_total_no_exx ; -> hl, c|cy 0F6C: ED42 sbc hl,bc 0F6E: D0 ret nc ; jetzt passt's 0F6F: 0F6F: C32817 mas0 jp abort_oomem 0F72: 0F72: 0F72: 0F72: ; ---------------------------------------- 0F72: ; Pop Handle from Heap 0F72: ; 0F72: ; in: -- 0F72: ; out: hl -> handle **unprotected!** 0F72: ; mod: hl 0F72: 0F72: mem_heap_pop_handle_no_exx: 0F72: mem_heap_pop_handle: 0F72: 2A215B ld hl,(mem_heap_ptr) 0F75: 2B dec hl 0F76: 2B dec hl 0F77: 22215B ld (mem_heap_ptr),hl 0F7A: C9 ret 0F7B: 0F7B: 0F7B: ; -------------------------------------------------------- 0F7B: ; Get top handle on heap 0F7B: ; 0F7B: ; in: -- 0F7B: ; out: hl -> handle 0F7B: ; mod: hl 0F7B: 0F7B: mem_heap_peek_handle_no_exx: 0F7B: mem_heap_peek_handle: 0F7B: 2A215B ld hl,(mem_heap_ptr) 0F7E: 2B dec hl 0F7F: 2B dec hl 0F80: C9 ret 0F81: 0F81: 0F81: ; -------------------------------------------------------- 0F81: ; Get a new, free handle on heap 0F81: ; 0F81: ; in: -- 0F81: ; out: hl -> handle 0F81: ; mod: hl 0F81: 0F81: mem_heap_new_handle: 0F81: 2A215B ld hl,(mem_heap_ptr) ; allocate handle on heap 0F84: 23 inc hl 0F85: 3600 ld (hl),0 0F87: 23 inc hl 0F88: 22215B ld (mem_heap_ptr),hl 0F8B: 2B dec hl 0F8C: 2B dec hl 0F8D: C9 ret 0F8E: 0F8E: 0F8E: ; -------------------------------------------------------- 0F8E: ; Get a new, free handle 0F8E: ; 0F8E: ; in: -- 0F8E: ; out: hl -> handle 0F8E: ; mod: af, hl 0F8E: 0F8E: mem_new_handle: 0F8E: C5 push bc 0F8F: 010000 ld bc,0 0F92: CD630F call mem_assert_free 0F95: C1 pop bc 0F96: D5 push de 0F97: CD9C0F call mem_new_handle_quick 0F9A: D1 pop de 0F9B: C9 ret 0F9C: 0F9C: 0F9C: ; -------------------------------------------------------- 0F9C: ; Get a new, free handle 0F9C: ; note: 2 bytes free space must be checked beforehand! 0F9C: ; 0F9C: ; in: -- 0F9C: ; out: hl -> handle 0F9C: ; mod: af, de, hl 0F9C: 0F9C: mem_new_handle_quick: 0F9C: 97 sub a 0F9D: ED5B1B5B ld de,(mem_handles_start) 0FA1: 1B dec de 0FA2: 12 ld (de),a ; stopper.hi := 0 finales handle löschen 0FA3: 1B dec de ; de -> stopper = mem_handles_start -2 0FA4: 0FA4: 2A1D5B ld hl,(mem_last_handle) 0FA7: 2B mnh1 dec hl ; hl -> prev_handle.hi 0FA8: BE cp (hl) 0FA9: 2B dec hl ; hl -> handle.lo 0FAA: 20FB jr nz,mnh1 ; handle.hi != 0 => belegt 0FAC: 0FAC: ; free handle found: hl 0FAC: 221D5B ld (mem_last_handle),hl ; update round robbin pointer 0FAF: ;and a 0FAF: ED52 sbc hl,de ; ist es der stopper? 0FB1: 19 add hl,de ; 0FB2: C0 ret nz ; nein 0FB3: 221B5B ld (mem_handles_start),hl ; ja => update mem_handles_start 0FB6: C9 ret 0FB7: 0FB7: 0FB7: 0FB7: ; -------------------------------------------------------- 0FB7: ; Reallocate (copy) data for handle 0FB7: ; 0FB7: ; in: hl->handle 0FB7: ; out: hl->handle 0FB7: ; de->data 0FB7: ; bc=size 0FB7: ; mod: af, bc, de 0FB7: 0FB7: mem_realloc_no_exx: 0FB7: mem_realloc: 0FB7: CD540F call mem_get_size_no_exx ; bc=size 0FBA: EB ex hl,de ; de->handle 0FBB: CD5E0F call mem_assert_size_no_exx ; check free space 0FBE: 626B ld hl,de ; hl->handle 0FC0: CD4D0F call mem_get_address_no_exx ; hl->old data 0FC3: E5 push hl ; sp:->old data 0FC4: EB ex hl,de ; hl->handle 0FC5: CDE00F call ma2 ; hl->handle de->new data bc:size 0FC8: E3 ex hl,(sp) ; sp:->handle hl->old data 0FC9: D5 push de 0FCA: C5 push bc 0FCB: C42810 call nz,ldir 0FCE: C1 pop bc ; bc:size 0FCF: D1 pop de ; de->data 0FD0: E1 pop hl ; hl->handle 0FD1: C9 ret 0FD2: 0FD2: 0FD2: 0FD2: ; -------------------------------------------------------- 0FD2: ; Allocate memory. 0FD2: ; Runs mem_compact if requested size is not immediately available. 0FD2: ; Aborts with Out-of-memory if after mem_compact is still not enough memory free. 0FD2: ; 0FD2: ; The memory is not cleared 0FD2: ; The maximum size for BC is mem_max_size-1. ($5FFF) 0FD2: ; If 0 bytes are requested, then a handle with a pointer to mem_empty_data is returned. 0FD2: ; 0FD2: ; mem_alloc: allocates a handle for global data 0FD2: ; mem_heap_alloc: allocates a handle on the heap 0FD2: ; 0FD2: ; in: bc = requested size 0FD2: ; out: f: z: bc=0 0FD2: ; nz: bc>0 0FD2: ; hl -> handle 0FD2: ; de -> data 0FD2: ; bc = size (pres.) 0FD2: ; mod: af, de, hl 0FD2: 0FD2: mem_heap_alloc: 0FD2: CD5E0F call mem_assert_size ; check size & space 0FD5: CD810F call mem_heap_new_handle ; allocate handle on heap 0FD8: 1806 jr ma2 ; allocate data 0FDA: 0FDA: mem_alloc: 0FDA: CD5E0F call mem_assert_size ; check size bc & free space 0FDD: CD9C0F call mem_new_handle_quick ; hl -> free handle 0FE0: 0FE0: ; allocate data 0FE0: 78 ma2 ld a,b 0FE1: B1 or c 0FE2: 2815 jr z,ma3 ; return mem_empty_data for 0-byte request 0FE4: 0FE4: ED5B195B ld de,(mem_data_end) ; de -> my_data.size 0FE8: 73 ld (hl),e ; store data address in handle 0FE9: 23 inc hl 0FEA: 72 ld (hl),d 0FEB: 2B dec hl ; hl -> handle 0FEC: 0FEC: EB ex hl,de ; hl -> data.size; de->handle 0FED: 71 ld (hl),c ; store size in data.size 0FEE: 23 inc hl 0FEF: 70 ld (hl),b 0FF0: 23 inc hl ; hl->data.data 0FF1: 0FF1: 09 add hl,bc ; hl->data.end 0FF2: 22195B ld (mem_data_end),hl 0FF5: ED42 sbc hl,bc ; hl->data.data 0FF7: 0FF7: EB ex hl,de ; hl -> handle; de -> data.data 0FF8: C9 ret ; nz 0FF9: 0FF9: ; return mem_empty_data for a 0 byte request 0FF9: 0FF9: mem_set_empty_data: 0FF9: 11750E ma3: ld de,mem_empty_data 0FFC: 73 ld (hl),e ; store data address in handle 0FFD: 23 inc hl 0FFE: 72 ld (hl),d 0FFF: 2B dec hl ; hl -> handle 1000: C9 ret ; z ; bc = 0 1001: 1001: 1001: 1001: ; --------------------------------------- 1001: ; Reserviere Speicher und speichere Daten darin 1001: ; 1001: ; mem_save_data: alloc with mem_alloc for global data 1001: ; mem_heap_push_data: alloc with mem_heap_alloc on heap 1001: ; 1001: ; in: hl -> source data 1001: ; bc = data size 1001: ; out: hl -> handle 1001: ; de -> data 1001: ; mod: af, de, hl 1001: 1001: mem_heap_push_data_no_exx: 1001: mem_heap_push_data: 1001: E5 push hl 1002: CDD20F call mem_heap_alloc 1005: 1804 jr msd1 1007: 1007: mem_save_data: 1007: E5 push hl ; sp:sourceptr 1008: CDDA0F call mem_alloc ; hl:handleptr de:destptr bc:size z|nz 100B: E3 msd1 ex hl,(sp) ; sp:handleptr; hl:sourceptr; de:destptr 100C: 100C: C5 push bc 100D: D5 push de 100E: C42810 call nz,ldir 1011: D1 pop de 1012: C1 pop bc 1013: 1013: E1 pop hl ; hl -> handle 1014: C9 ret 1015: 1015: 1015: 1015: ; ------------------------------------------------------------ 1015: ; Restore saved data and release handle. 1015: ; 1015: ; in: hl -> handle 1015: ; de -> dest. 1015: ; out: -- 1015: ; mod: af 1015: 1015: mem_restore_data: 1015: D7 rst save_registers 1016: CD2210 call mem_copy_data_to_de ; handle hl -> addr de 1019: ;jr mem_dealloc 1019: 1019: 1019: ; -------------------------------------------------------- 1019: ; Release handle and data. 1019: ; 1019: ; in: hl -> handle 1019: ; out: -- 1019: ; mod: -- 1019: 1019: mem_dealloc: 1019: 23 inc hl 101A: 3600 ld (hl),0 ; handle.hi := 0 101C: 2B dec hl 101D: C9 ret 101E: 101E: 101E: ; ------------------------------------------------------------ 101E: ; Restore data from data on heap and pop handle. 101E: ; 101E: ; in: de -> dest. 101E: ; out: -- 101E: ; mod: af 101E: 101E: mem_heap_pop_data_no_exx: 101E: mem_heap_pop_data: 101E: D7 rst save_registers 101F: CD720F call mem_heap_pop_handle ; hl -> dropped handle 1022: ;jr mem_copy_data_to_de ; handle hl -> addr de 1022: 1022: 1022: ; -------------------------------------------------------- 1022: ; UP: copy data from data for handle HL to destination DE 1022: ; 1022: ; in: hl -> handle 1022: ; de -> destination 1022: ; out: de -> behind destination 1022: ; mod: af, bc, de, hl 1022: 1022: mem_copy_data_to_de: 1022: CD440F call mem_get_size_and_address ; hl->data bc:size 1025: ;jr ldir_if_nz 1025: 1025: 1025: ; --------------------------------------------- 1025: ; UP: ldir if bc > 0 1025: ; 1025: ; in: bc, de, hl as for ldir 1025: ; out: bc, de, hl as after ldir 1025: ; mod: af, bc, de, hl 1025: 1025: ldir_if_nz: 1025: 78 ld a,b 1026: B1 or c 1027: C8 ret z 1028: EDB0 ldir: ldir 102A: C9 ret 102B: 102B: 102B: ; --------------------------------------------- 102B: ; push handle on heap 102B: ; 102B: ; in: hl -> handle 102B: ; out: hl -> handle on stack 102B: ; mod: hl 102B: 102B: mem_heap_push_handle: 102B: D5 push de 102C: 5E ld e,(hl) 102D: 23 inc hl 102E: 56 ld d,(hl) ; de -> data.size 102F: 2A215B ld hl,(mem_heap_ptr) 1032: 73 ld (hl),e 1033: 23 inc hl 1034: 72 ld (hl),d 1035: 23 inc hl 1036: 22215B ld (mem_heap_ptr),hl 1039: 2B dec hl 103A: 2B dec hl 103B: D1 pop de 103C: C9 ret 103D: 103D: 103D: ; --------------------------------------------- 103D: ; access handle at calculated offset in stack 103D: ; 103D: ; in: de = index in stack; 1=topmost 103D: ; out: hl -> handle 103D: ; mod: hl 103D: 103D: mem_heap_pick_handle: 103D: 2A215B ld hl,(mem_heap_ptr) 1040: A7 and a 1041: ED52 sbc hl,de 1043: ED52 sbc hl,de 1045: C9 ret 1046: 1046: 1046: ; --------------------------------------------- 1046: ; swap 1st and 2nd handle on heap 1046: ; 1046: ; in: -- 1046: ; out: -- 1046: ; mod: -- 1046: 1046: mem_heap_swap_handles 1046: D9 exx 1047: 2A215B ld hl,(mem_heap_ptr) 104A: 104A: 2B dec hl 104B: 56 ld d,(hl) 104C: 2B dec hl 104D: 5E ld e,(hl) 104E: 2B dec hl 104F: 46 ld b,(hl) 1050: 2B dec hl 1051: 4E ld c,(hl) 1052: 1052: 73 ld (hl),e 1053: 23 inc hl 1054: 72 ld (hl),d 1055: 23 inc hl 1056: 71 ld (hl),c 1057: 23 inc hl 1058: 70 ld (hl),b 1059: D9 exx 105A: C9 ret 105B: 105B: 105B: 105B: #if 0 105B: 105B: ; --------------------------------------------- 105B: ; grow data for handle 105B: ; relocate data and grow size 105B: ; new data is not cleared 105B: ; 105B: ; in: hl -> handle 105B: ; bc = new size 105B: ; out: hl -> handle 105B: ; de -> data 105B: ; bc = new size 105B: ; mod: af de 105B: 105B: mem_grow_data_no_exx: 105B: mem_grow_data: 105B: push bc ; sp:new size 105B: call mem_realloc_no_exx ; hl->handle de->data bc=oldsize 105B: pop de ; hl->handle de=newsize bc=oldsize 105B: push hl ; sp:handle 105B: 105B: ld hl,de ; hl=newsize de=newsize bc=oldsize 105B: and a 105B: sbc hl,bc ; hl=growth de=newsize bc=oldsize 105B: call nc,mem_assert_free_no_exx; de=newsize bc=oldsize **may run mem_compact** 105B: pop hl ; hl->handle 105B: ld bc,de ; bc=newsize 105B: 105B: ld de,(hl) ; de->data.size hl->handle 105B: ex hl,de ; hl->data.size de->handle bc=newsize 105B: 105B: ld (hl),c 105B: inc hl 105B: ld (hl),b ; store new size in data.size 105B: inc hl ; hl->data.data 105B: 105B: add hl,bc ; hl->data.newend 105B: ld (mem_data_end),hl ; update sysvar 105B: sbc hl,de ; hl->data.data 105B: 105B: ex hl,de ; de->data.data hl->handle bc=newsize 105B: ret 105B: 105B: #endif 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: 105B: #include "mem.ass" 105B: 105B: 105B: 105B: 105B: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 105B: ; Virtual Machine Opcodes 105B: 105B: ; string "text\0" -- {str} push immediate text 105B: ; {str} dupstr -- {str} {str} shared data! 105B: ; {str} unsharestr -- {str} 105B: ; {str} dropstr -- 105B: ; {str2} {str1} nipstr -- {str1} 105B: ; {str2} {str1} swapstr -- {str1} {str2} 105B: ; {str_n} .. {str1} pickstr -- {str_n} .. {str1} {str_i} shared data! 105B: 105B: ; {str} {str} catstr -- {str} 105B: ; {str} leftstr -- {str} 105B: ; {str} rightstr -- {str} 105B: ; {str} midstr -- {str} 105B: ; {str} substr -- {str} 105B: 105B: ; {str} strlen -- 105B: ; {str} strdata -- 105B: 105B: ; {str} upperstr -- {str} 105B: ; {str} lowerstr -- {str} 105B: 105B: ; charstr -- {str} 105B: ; {str} charcode -- 105B: ; emptystr -- {str} 105B: ; spacestr -- {str} 105B: 105B: ; initstrvar -- legt handle für empty string an 105B: ; killstrvar -- killt handle 105B: ; peekstr -- {str} shared data! 105B: ; {str} pokestr -- überschreibt den Descriptor! 105B: 105B: ; pushdata -- {str} 105B: ; {str} popdata -- 105B: 105B: 105B: 105B: ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 105B: 105B: 105B: 105B: ; ------------------------------------- 105B: ; push immediate string 105B: ; string "text literal",0 -- {string} 105B: 105B: v_string 105B: D5 push de ; sp:top item 105C: C5 push bc ; sp:->text 105D: 105D: 6069 ld hl,bc 105F: 97 sub a 1060: BE vs1 cp (hl) 1061: 23 inc hl 1062: 20FC jr nz,vs1 ; hl->hinter 0; bc->text 1064: 1064: 37 scf 1065: ED42 sbc hl,bc ; hl:len 1067: 444D ld bc,hl ; bc:len 1069: 1069: CDD20F call mem_heap_alloc ; hl:handle de->data bc:size z|nz 106C: E1 pop hl ; hl->text de->data bc:size z|nz 106D: C42810 call nz,ldir ; hl->0 1070: 23 inc hl ; hl->hinter 0 1071: 1071: 444D ld bc,hl ; bc = neuer pc 1073: D1 pop de ; de:top item 1074: FDE9 jp (iy) 1076: 1076: 1076: 1076: ; -------------------------------------------------------- 1076: ; Get data address for string. 1076: ; {string} straddr -- 1076: 1076: v_straddr: 1076: D5 push de 1077: CD720F call mem_heap_pop_handle ; hl->handle 107A: 5E ld e,(hl) 107B: 23 inc hl 107C: 56 ld d,(hl) 107D: 13 inc de 107E: 13 inc de 107F: FDE9 jp (iy) 1081: 1081: 1081: 1081: ; -------------------------------------------------------- 1081: ; Get data size for string. 1081: ; {str} strlen -- 1081: 1081: v_strlen: 1081: D5 push de 1082: CD720F call mem_heap_pop_handle ; hl->handle 1085: 5E ld e,(hl) 1086: 23 inc hl 1087: 56 ld d,(hl) 1088: EB ex hl,de ; hl->data.size 1089: 5E ld e,(hl) 108A: 23 inc hl 108B: 56 ld d,(hl) ; de=size 108C: FDE9 jp (iy) 108E: 108E: 108E: ; -------------------------------------------------------- 108E: ; Duplicate string on heap. 108E: ; Shared data! 108E: ; {str} dupstr -- {str} {str} 108E: 108E: v_dupstr 108E: CD7B0F call mem_heap_peek_handle ; hl->handle 1091: CD2B10 call mem_heap_push_handle 1094: FDE9 jp (iy) 1096: 1096: 1096: ; -------------------------------------------------------- 1096: ; Drop string on heap. 1096: ; {str} dropstr -- 1096: 1096: v_dropstr 1096: CD720F call mem_heap_pop_handle 1099: FDE9 jp (iy) 109B: 109B: 109B: ; -------------------------------------------------------- 109B: ; Reallocate string on heap. 109B: ; {str} unsharestr -- {str} 109B: 109B: v_unsharestr 109B: D9 exx 109C: CD7B0F call mem_heap_peek_handle_no_exx 109F: CDB70F call mem_realloc_no_exx 10A2: D9 exx 10A3: FDE9 jp (iy) 10A5: 10A5: 10A5: ; -------------------------------------------------------- 10A5: ; Drop 2nd string on heap. 10A5: ; {str2} {str1} nipstr -- {str1} 10A5: 10A5: v_nipstr 10A5: CD4610 call mem_heap_swap_handles 10A8: CD720F call mem_heap_pop_handle 10AB: FDE9 jp (iy) 10AD: 10AD: ; -------------------------------------------------------- 10AD: ; Exchange 1st and 2nd string on heap 10AD: ; {str2} {str1} swapstr -- {str1} {str2} 10AD: 10AD: v_swapstr 10AD: CD4610 call mem_heap_swap_handles 10B0: FDE9 jp (iy) 10B2: 10B2: 10B2: ; -------------------------------------------------------- 10B2: ; pick and dup a calculated string on heap. 10B2: ; shared data! 10B2: ; {str_n} .. {str1} pickstr -- {str_n} .. {str1} {str_i} 10B2: 10B2: v_pickstr 10B2: CD3D10 call mem_heap_pick_handle 10B5: CD2B10 call mem_heap_push_handle 10B8: FDE9 jp (iy) 10BA: 10BA: 10BA: ; -------------------------------------------------------- 10BA: ; convert string to uppercase 10BA: ; {str} upperstr -- {str} 10BA: 10BA: v_upperstr 10BA: D5 push de 10BB: C5 push bc 10BC: CD7B0F call mem_heap_peek_handle 10BF: CDB70F call mem_realloc ; hl->handle de->data bc=size 10C2: 10C2: 0C inc c 10C3: 04 inc b 10C4: 180B jr us1 10C6: 7E us2 ld a,(hl) 10C7: D661 sub 'a' 10C9: FE7B cp 'z'+1 10CB: 3003 jr nc,us3 10CD: C641 add 'A' 10CF: 77 ld (hl),a 10D0: 23 us3 inc hl 10D1: 0D us1 dec c 10D2: 20F2 jr nz,us2 10D4: 10F0 djnz us2 10D6: 10D6: C1 pop bc 10D7: D1 pop de 10D8: FDE9 jp (iy) 10DA: 10DA: 10DA: ; -------------------------------------------------------- 10DA: ; convert string to lowercase 10DA: ; {str} lowerstr -- {str} 10DA: 10DA: v_lowerstr 10DA: D5 push de 10DB: C5 push bc 10DC: CD7B0F call mem_heap_peek_handle 10DF: CDB70F call mem_realloc ; hl->handle de->data bc=size 10E2: 10E2: 0C inc c 10E3: 04 inc b 10E4: 180B jr ls1 10E6: 7E ls2 ld a,(hl) 10E7: D641 sub 'A' 10E9: FE5B cp 'Z'+1 10EB: 3003 jr nc,ls3 10ED: C661 add 'a' 10EF: 77 ld (hl),a 10F0: 23 ls3 inc hl 10F1: 0D ls1 dec c 10F2: 20F2 jr nz,ls2 10F4: 10F0 djnz ls2 10F6: 10F6: C1 pop bc 10F7: D1 pop de 10F8: FDE9 jp (iy) 10FA: 10FA: 10FA: ; ------------------------------------- 10FA: ; convert character code to 1-letter text string 10FA: ; charstr -- {str} 10FA: 10FA: v_charstr 10FA: C5 push bc 10FB: 10FB: D5 push de 10FC: 010100 ld bc,1 10FF: CDD20F call mem_heap_alloc ; hl:handle de->data bc=size 1102: EB ex hl,de ; de-> handle hl->data 1103: C1 pop bc ; value 1104: 71 ld (hl),c 1105: 1105: C1 pop bc ; pc 1106: D1 pop de ; top item 1107: FDE9 jp (iy) 1109: 1109: 1109: 1109: ; ------------------------------------- 1109: ; convert 1st character of string to character code 1109: ; {str} charcode -- 1109: 1109: v_charcode 1109: D5 push de 110A: CD720F call mem_heap_pop_handle ; hl->handle 110D: CD4D0F call mem_get_address ; hl->data 1110: 110000 ld de,0 1113: 3E0E ld a,+(mem_empty_data+2)/256 ; empty string? 1115: BC cp h 1116: 2801 jr z,$+3 ; yes -> top item := 0 1118: 5E ld e,(hl) ; no -> top item := charcode 1119: FDE9 jp (iy) 111B: 111B: 111B: 111B: ; ------------------------------------- 111B: ; push empty string of defined size 111B: ; spacestr -- {str} 111B: 111B: v_spacestr: 111B: C5 push bc 111C: 111C: EB ex hl,de 111D: CDD20F call mem_heap_alloc ; hl->handle de->data bc:size 1120: EB ex hl,de ; hl->data bc:size 1121: 1E20 ld e,' ' ; filler 1123: C4210C call nz,clear_bc_e 1126: 1126: C1 pop bc 1127: D1 pop de 1128: FDE9 jp (iy) 112A: 112A: 112A: 112A: ; -------------------------------------------------------- 112A: ; push an empty string 112A: ; emptystr -- {str} 112A: 112A: v_emptystr 112A: 2A215B ld hl,(mem_heap_ptr) 112D: 3675 ld (hl),mem_empty_data%256 112F: 23 inc hl 1130: 360E ld (hl),mem_empty_data/256 1132: 23 inc hl 1133: 22215B ld (mem_heap_ptr),hl 1136: FDE9 jp (iy) 1138: 1138: 1138: 1138: ; ------------------------------------- 1138: ; initialize a string variable 1138: ; legt handle für empty string an 1138: ; initstrvar -- 1138: 1138: v_initstrvar: 1138: EB ex hl,de 1139: 3675 ld (hl),mem_empty_data%256 113B: 23 inc hl 113C: 360E ld (hl),mem_empty_data/256 113E: D1 pop de 113F: FDE9 jp (iy) 1141: 1141: 1141: ; ------------------------------------- 1141: ; kill a string variable 1141: ; killt handle 1141: ; killstrvar -- 1141: 1141: v_killstrvar: 1141: EB ex hl,de ; hl->strvar 1142: 5E ld e,(hl) 1143: 23 inc hl 1144: 56 ld d,(hl) ; de->handle 1145: EB ex hl,de ; hl->handle 1146: 23 inc hl 1147: 3600 ld (hl),0 ; handle.hi := 0 1149: 1149: D1 pop de ; top item 114A: FDE9 jp (iy) 114C: 114C: 114C: 114C: ; ------------------------------------- 114C: ; dup data from string var on the heap 114C: ; shared data! 114C: ; peekstr -- {str} 114C: 114C: v_peekstr: 114C: EB ex hl,de ; hl->strvar 114D: 5E ld e,(hl) 114E: 23 inc hl 114F: 56 ld d,(hl) ; de->handle 1150: EB ex hl,de ; hl->handle 1151: CD2B10 call mem_heap_push_handle 1154: D1 pop de ; top item 1155: FDE9 jp (iy) 1157: 1157: 1157: ; ------------------------------------- 1157: ; dup data from string var on the heap 1157: ; overwrites the handle, not the pointer in the var! 1157: ; {str} pokestr -- 1157: 1157: v_pokestr: 1157: EB ex hl,de ; hl->strvar 1158: 5E ld e,(hl) 1159: 23 inc hl 115A: 56 ld d,(hl) ; de->old handle 115B: 115B: CD720F call mem_heap_pop_handle ; hl->new handle 115E: 7E ld a,(hl) 115F: 23 inc hl 1160: 66 ld h,(hl) 1161: 6F ld l,a ; hl -> new data 1162: 1162: EB ex hl,de ; hl->old handle de->new data 1163: 73 ld (hl),e 1164: 23 inc hl 1165: 72 ld (hl),d ; store ptr to new data in old handle 1166: 1166: D1 pop de ; top item 1167: FDE9 jp (iy) 1169: 1169: 1169: ; ------------------------------------- 1169: ; push arbitrary block of data on heap 1169: ; pushdata -- {str} 1169: 1169: v_pushdata: 1169: E1 pop hl ; hl->data 116A: C5 push bc ; pc 116B: 424B ld bc,de ; bc=size 116D: CD0110 call mem_heap_push_data 1170: 1170: C1 pop bc ; pc 1171: D1 pop de ; top item 1172: FDE9 jp (iy) 1174: 1174: 1174: ; ------------------------------------- 1174: ; restore memory from data on heap 1174: ; {str} popdata -- 1174: 1174: v_popdata: 1174: CD1E10 call mem_heap_pop_data 1177: D1 pop de 1178: FDE9 jp (iy) 117A: 117A: 117A: 117A: ; ---------------------------------------------------- 117A: ; Concatenate two strings 117A: ; {str1} {str2} catstr -- {str} 117A: 117A: v_catstr: 117A: C5 push bc 117B: D5 push de 117C: 117C: CD7B0F call mem_heap_peek_handle ; hl -> str2 117F: CD540F call mem_get_size ; bc=str2.size 1182: 5059 ld de,bc ; de=str2.size 1184: 1184: 2B dec hl 1185: 2B dec hl ; hl -> str1 1186: CD540F call mem_get_size ; bc=str1.size 1189: 1189: EB ex hl,de 118A: 09 add hl,bc ; hl=size1+size2 118B: 444D ld bc,hl ; bc=size1+size2 118D: CDD20F call mem_heap_alloc ; hl->newhandle de->newdata bc=newsize 1190: E5 push hl ; sp->newhandle 1191: 1191: 2B dec hl 1192: 2B dec hl ; hl -> str2 1193: E5 push hl ; sp -> str2 1194: 1194: 2B dec hl 1195: 2B dec hl ; hl -> str1 1196: CD440F call mem_get_size_and_address ; hl->data1 bc=size1 de->newdata 1199: CD2510 call ldir_if_nz 119C: 119C: E1 pop hl ; hl->str2 119D: CD440F call mem_get_size_and_address ; hl->data2 bc=size2 de->newdata 11A0: CD2510 call ldir_if_nz 11A3: 11A3: E1 pop hl ; hl->newstr 11A4: 5E23562B ld de,(hl) ; de=newstr 11A8: 11A8: 2B dec hl 11A9: 2B dec hl ; hl->str2 11AA: 22215B ld (mem_heap_ptr),hl ; drop str2 and newstr 11AD: 11AD: 2B dec hl 11AE: 72 ld (hl),d 11AF: 2B dec hl ; hl->str1 11B0: 73 ld (hl),e ; str1 := newstr 11B1: 11B1: D1 pop de 11B2: C1 pop bc 11B3: FDE9 jp (iy) 11B5: 11B5: 11B5: ; ------------------------------------------------ 11B5: ; UP: validate index hl 11B5: ; 11B5: ; in: hl = index 11B5: ; bc = size 11B5: ; out: hl = adjusted index: [0..hl..bc] 11B5: ; mod: af, hl 11B5: 11B5: str_validate_hl_and_de 11B5: EB ex hl,de 11B6: CDBA11 call str_validate_index 11B9: EB ex hl,de 11BA: 11BA: str_validate_index 11BA: 7C ld a,h 11BB: 07 rlca 11BC: 3807 jr c,vd1 ; hl < 0 11BE: 11BE: ;and a 11BE: ED42 sbc hl,bc ; cp hl,bc 11C0: 09 add hl,bc 11C1: D8 ret c ; hl=bc => hl:=bc 11C4: C9 ret 11C5: 11C5: 210000 vd1 ld hl,0 11C8: C9 ret 11C9: 11C9: 11C9: 11C9: ; --------------------------------------------- 11C9: ; UP: create substring 11C9: ; no validating! 11C9: ; {str} v_quicksubstr {str} 11C9: 11C9: v_quicksubstr: 11C9: EB ex hl,de ; hl=idx2 11CA: D1 pop de ; de=idx1 11CB: 11CB: C5 push bc ; sp:pc 11CC: 11CC: A7 and a 11CD: ED52 sbc hl,de ; hl=size de=idx1 11CF: 11CF: ; hl=newsize > 0 11CF: ; de=index1 11CF: ; sp:pc 11CF: 11CF: 444D vqss1 ld bc,hl ; bc=size de=idx1 11D1: D5 push de ; sp:idx1 11D2: 11D2: CDD20F call mem_heap_alloc ; hl:newhandle de->newdata bc:newsize 11D5: 2B dec hl 11D6: 2B dec hl ; hl:oldhandle de->newdata bc:newsize 11D7: 11D7: CD4D0F call mem_get_address ; hl->olddata 11DA: EB ex hl,de 11DB: E3 ex hl,(sp) ; sp:->newdata 11DC: EB ex hl,de ; de:idx1 hl->olddata bc:newsize 11DD: 19 add hl,de ; hl->olddataatidx bc:newsize 11DE: D1 pop de ; hl->olddataatidx de->newdata bc:newsize 11DF: CD2510 call ldir_if_nz 11E2: 11E2: C1 pop bc ; pc 11E3: C3A510 jp v_nipstr 11E6: 11E6: 11E6: 11E6: ; --------------------------------------------- 11E6: ; create substring 11E6: ; {str} midstr -- {str} 11E6: 11E6: v_midstr: 11E6: E1 pop hl 11E7: E5 push hl 11E8: 19 add hl,de 11E9: EB ex hl,de 11EA: ;jr v_substr 11EA: 11EA: 11EA: ; --------------------------------------------- 11EA: ; create substring 11EA: ; {str} substr -- {str} 11EA: 11EA: v_substr: 11EA: E1 pop hl ; hl=idx1 de=idx2 11EB: C5 push bc ; sp:pc 11EC: 11EC: E5 push hl 11ED: CD7B0F call mem_heap_peek_handle 11F0: CD540F call mem_get_size ; bc=size 11F3: E1 pop hl 11F4: 11F4: CDB511 call str_validate_hl_and_de 11F7: EB ex hl,de ; hl=idx1 de=idx2 11F8: 37 scf 11F9: ED52 sbc hl,de ; idx2-idx1-1 11FB: 3803 jr c,vss0 ; idx2-idx1-1<0 <=> idx2 <= idx1 11FD: 23 inc hl ; hl=idx2-idx1 = newsize 11FE: 18CF jr vqss1 1200: 1200: CD7B0F vss0 call mem_heap_peek_handle 1203: CDF90F call mem_set_empty_data 1206: C1 pop bc 1207: D1 pop de 1208: FDE9 jp (iy) 120A: 120A: 120A: ; --------------------------------------------- 120A: ; create substring 120A: ; {str} leftstr -- {str} 120A: 120A: v_leftstr: 120A: C5 push bc ; sp:pc 120B: 120B: CD7B0F call mem_heap_peek_handle 120E: CD540F call mem_get_size ; bc=size 1211: EB ex hl,de 1212: CDBA11 call str_validate_index 1215: 110000 ld de,0 ; hl=size de=idx1 1218: 18B5 jr vqss1 121A: 121A: 121A: ; --------------------------------------------- 121A: ; create substring 121A: ; {str} rightstr -- {str} 121A: 121A: v_rightstr: 121A: C5 push bc ; sp:pc 121B: CD7B0F call mem_heap_peek_handle 121E: CD540F call mem_get_size ; bc=size 1221: EB ex hl,de ; hl=newsize 1222: CDBA11 call str_validate_index 1225: 1225: EB ex hl,de ; de=newsize 1226: 6069 ld hl,bc ; hl=bc=oldsize 1228: A7 and a 1229: ED52 sbc hl,de ; hl=cropsize=idx1 122B: EB ex hl,de ; de=idx1 hl=newsize 122C: 18A1 jr vqss1 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: 122E: #include "str.ass" 122E: mempack_end equ $ 122E: 122E: vip_start equ $ 122E: 122E: 122E: ; -------------------------------------------- 122E: ; Virtual Machine 122E: ; -------------------------------------------- 122E: 122E: ; Start: rst vip 122E: ; Stop: defb to_real 122E: ; dispatcher entry: IY 122E: ; instruction pointer: BC 122E: ; return stack: SP 122E: ; data heap: SP (mixed with return addresses) 122E: ; top item of heap: DE 122E: ; local variables: IX 122E: 122E: 122E: v_scratch data 6 122E: 122E: 122E: ; ---------------------------------------- 122E: ; Init virtual machine 122E: ; 122E: 122E: init_vip: 122E: C9 ret 122F: 122F: 122F: 122F: ; ---------------------------------------- 122F: ; Switch to virtual 122F: ; 122F: ; RST entry 122F: ; 122F: ; in: de: top stack item 122F: ; out: de: top stack item 122F: ; mod: 122F: 122F: #if 0 122F: 122F: vip: pop bc ; bc = vip pc 122F: vip_iy: ; auxiliary entry 122F: ld iy,vip_dis ; vip dispatcher entry 122F: jp (iy) 122F: 122F: #endif 122F: 122F: 122F: 122F: ; ---------------------------------- 122F: ; virtual instruction processor 122F: ; program execution dispatcher 122F: 122F: 0A vip_dis ld a,(bc) 1230: 03 inc bc 1231: 2614 ld h,v_tab>>8 1233: 6F ld l,a 1234: E9 jp (hl) 1235: 1235: 1235: 1235: ; ------------------------------------- 1235: ; opcode implementations 1235: ; ------------------------------------- 1235: 1235: 1235: ; ------------------------------------- 1235: ; calculate unsigned maximum value 1235: ; umax -- 1235: 1235: E1 v_umax pop hl 1236: A7 and a 1237: ED52 vum1 sbc hl,de 1239: 38F4 jr c,vip_dis ; jp c,(iy) 123B: 19 add hl,de 123C: EB ex hl,de 123D: FDE9 jp (iy) 123F: 123F: ; ------------------------------------- 123F: ; calculate unsigned minimum value 123F: ; umin -- 123F: 123F: E1 v_umin pop hl 1240: A7 and a 1241: ED52 vum2 sbc hl,de 1243: 30EA jr nc,vip_dis ; jp c,(iy) 1245: 19 add hl,de 1246: EB ex hl,de 1247: FDE9 jp (iy) 1249: 1249: ; ------------------------------------- 1249: ; calculate signed maximum value 1249: ; max -- 1249: 1249: E1 v_max pop hl 124A: 7A ld a,d 124B: AC xor h 124C: F23712 jp p,vum1 124F: 18F0 jr vum2 1251: 1251: ; ------------------------------------- 1251: ; calculate signed minimum value 1251: ; min -- 1251: 1251: E1 v_min pop hl 1252: 7A ld a,d 1253: AC xor h 1254: F24112 jp p,vum2 1257: 18DE jr vum1 1259: 1259: ; ------------------------------------- 1259: ; execute next 1-byte opcode only if result is true 1259: ; else the opcode is skipped 1259: ; if -- 1259: 1259: 7A v_if ld a,d 125A: B3 or e 125B: D1 pop de 125C: 2810 jr z,skip1 125E: FDE9 jp (iy) 1260: 1260: ; ------------------------------------- 1260: ; execute next 2-byte opcode only if result is true 1260: ; else the opcode is skipped 1260: ; iff -- 1260: 1260: 7A v_iff ld a,d 1261: B3 or e 1262: D1 pop de 1263: 2808 jr z,skip2 1265: FDE9 jp (iy) 1267: 1267: ; ------------------------------------- 1267: ; execute next 3-byte opcode only if result is true 1267: ; else the opcode is skipped 1267: ; ifff -- 1267: 1267: 7A v_ifff ld a,d 1268: B3 or e 1269: D1 pop de 126A: 20C3 jr nz,vip_dis 126C: 03 skip3 inc bc 126D: 03 skip2 inc bc 126E: 03 skip1 inc bc 126F: FDE9 jp (iy) 1271: 1271: ; ------------------------------------- 1271: ; push immediate byte sign extended 1271: ; byte -- 1271: 1271: D5 v_byte push de 1272: 0A ld a,(bc) 1273: 03 inc bc 1274: FE db $fe ; cp a,N 1275: ;jr bp1 1275: 1275: ; ------------------------------------- 1275: ; peek byte sign extended 1275: ;
peekb -- 1275: 1275: 1A v_peekb ld a,(de) 1276: 1276: 5F bp1 ld e,a 1277: 87 add a 1278: 9F sbc a 1279: 57 ld d,a 127A: FDE9 jp (iy) 127C: 127C: ; ------------------------------------- 127C: ; push immediate word 127C: ; push -- 127C: 127C: v_number 127C: D5 push de 127D: 0A ld a,(bc) 127E: 03 inc bc 127F: 5F ld e,a 1280: 0A ld a,(bc) 1281: 03 inc bc 1282: 57 ld d,a 1283: FDE9 jp (iy) 1285: 1285: ; ------------------------------------- 1285: ; peek word 1285: ;
peek -- 1285: 1285: EB v_peek ex hl,de 1286: 5E ld e,(hl) 1287: 23 inc hl 1288: 56 ld d,(hl) 1289: FDE9 jp (iy) 128B: 128B: ; ------------------------------------- 128B: ; poke word 128B: ;
poke -- 128B: 128B: EB v_poke ex hl,de 128C: D1 pop de 128D: 73 ld (hl),e 128E: 23 inc hl 128F: 72 ld (hl),d 1290: D1 pop de 1291: FDE9 jp (iy) 1293: 1293: ; ------------------------------------- 1293: ; poke byte 1293: ;
pokeb -- 1293: 1293: EB v_pokeb ex hl,de 1294: D1 pop de 1295: 73 ld (hl),e 1296: D1 pop de 1297: FDE9 jp (iy) 1299: 1299: ; ------------------------------------- 1299: ; duplicate 2nd on stack value 1299: ; over -- 1299: 1299: E1 v_over pop hl 129A: E5 push hl 129B: D5 push de 129C: EB ex hl,de 129D: FDE9 jp (iy) 129F: 129F: ; ------------------------------------- 129F: ; duplicate value from stack by index 129F: ; ... pick -- ... 129F: 129F: EB v_pick ex hl,de 12A0: 2B dec hl 12A1: 29 add hl,hl 12A2: 39 add hl,sp 12A3: 5E ld e,(hl) 12A4: 23 inc hl 12A5: 56 ld d,(hl) 12A6: FDE9 jp (iy) 12A8: 12A8: ; ------------------------------------- 12A8: ; Set bit [15=left..0=right] 12A8: ; setbit -- 12A8: 12A8: v_setbit 12A8: 7B ld a,e 12A9: CD791F call calc_bmask 12AC: CB5B bit 3,e 12AE: D1 pop de 12AF: 2004 jr nz,vsb1 12B1: B3 or e 12B2: 5F ld e,a 12B3: FDE9 jp (iy) 12B5: B2 vsb1 or d 12B6: 57 ld d,a 12B7: FDE9 jp (iy) 12B9: 12B9: ; ------------------------------------- 12B9: ; clear bit [15=left..0=right] 12B9: ; clrbit -- 12B9: 12B9: v_clrbit 12B9: 7B ld a,e 12BA: CD851F call calc_nmask 12BD: CB5B bit 3,e 12BF: D1 pop de 12C0: 2004 jr nz,vcb1 12C2: A3 and e 12C3: 5F ld e,a 12C4: FDE9 jp (iy) 12C6: A2 vcb1 and d 12C7: 57 ld d,a 12C8: FDE9 jp (iy) 12CA: 12CA: ; ------------------------------------- 12CA: ; jump to address 12CA: ; jump
-- 12CA: 12CA: 6069 v_jump ld hl,bc 12CC: 4E ld c,(hl) 12CD: 23 inc hl 12CE: 46 ld b,(hl) 12CF: FDE9 jp (iy) 12D1: 12D1: ; ------------------------------------- 12D1: ; branch to address at offset 12D1: ; the offset is based to the address of the 'bra' opcode 12D1: ; bra -- 12D1: 12D1: 0A v_bra ld a,(bc) ; offset 12D2: 0B dec bc ; pc back to opcode 12D3: 6F ld l,a ; l=a 12D4: 87 add a ; cy=vz 12D5: 9F sbc a ; sign extend 12D6: 67 ld h,a ; hl=offset 12D7: 09 add hl,bc ; hl=new pc 12D8: 444D ld bc,hl ; jump 12DA: FDE9 jp (iy) 12DC: 12DC: ; ------------------------------------- 12DC: ; branch to address at offset if condition is true 12DC: ; the offset is based to the address of the 'bra_if' opcode 12DC: ; bra_if -- 12DC: 12DC: v_bra_if 12DC: 7A ld a,d 12DD: B3 or e 12DE: D1 pop de 12DF: 20F0 jr nz,v_bra 12E1: 03 inc bc 12E2: FDE9 jp (iy) 12E4: 12E4: ; ------------------------------------- 12E4: ; branch to address at offset if condition is true 12E4: ; the offset is based to the address of the 'bra_if' opcode 12E4: ; bra_ifnot -- 12E4: 12E4: v_bra_ifnot 12E4: 7A ld a,d 12E5: B3 or e 12E6: D1 pop de 12E7: 28E8 jr z,v_bra 12E9: 03 inc bc 12EA: FDE9 jp (iy) 12EC: 12EC: ; ------------------------------------- 12EC: ; execute vip opcode at address 12EC: ; may be used to execute machine code sub routines 12EC: ; which conform, especially on exit, to the vip opcode interface: 12EC: ; de = top stack item 12EC: ; bc = pc 12EC: ; iy = vip_dis 12EC: ; return with 'jp (iy)' or 'jp vip_iy' or 'jp vip' 12EC: ; 12EC: ; opcode
-- 12EC: 12EC: v_opcode: 12EC: 0A ld a,(bc) 12ED: 03 inc bc 12EE: 6F ld l,a 12EF: 0A ld a,(bc) 12F0: 03 inc bc 12F1: 67 ld h,a 12F2: E9 jp (hl) 12F3: 12F3: ; ------------------------------------- 12F3: ; call a vip procedure 12F3: ; arguments and return value depend on called procedure. 12F3: ; it is recommended that the called procedure uses 'penter' and 'pexit' or 'preturn'. 12F3: ; else it must cope with the return address on the stack. 12F3: ; 12F3: ; [,..] call
-- [] 12F3: 12F3: D5 v_call push de ; push top value 12F4: 6069 ld hl,bc 12F6: 4E ld c,(hl) 12F7: 23 inc hl 12F8: 46 ld b,(hl) ; bc = pc = procedure address 12F9: 23 inc hl 12FA: EB ex hl,de ; top value = return address 12FB: FDE9 jp (iy) 12FD: 12FD: ; ------------------------------------- 12FD: ; return from procedure without local variables. 12FD: ; Notes: do not use 'penter'. 12FD: ; the top value after procedure entry is the return address! 12FD: ; you cannot manage local variables with lvar. 12FD: ; keep track of the stack contents. 12FD: ; remove all arguements before returning. 12FD: ; put the return address on top of the stack! 12FD: ; exit with 'exit' if you don't return a value, 12FD: ; else push the return value and exit with 'return'. 12FD: ; 'exit' and 'jp_calc' are effectively the same. 12FD: ; 'exit' can be substituted with 'swap' + 'return'. 12FD: ; 12FD: ; return a return value: 12FD: ; return -- 12FD: ; return nothing: 12FD: ; exit -- 12FD: 12FD: ;v_return 12FD: ; pop bc 12FD: ; jp (iy) 12FD: 12FD: ; ------------------------------------- 12FD: ; jump to calculated address 12FD: ; 'exit' and 'jp_calc' are effectively the same. 12FD: ;
jp_calc -- 12FD: 12FD: v_jp_calc 12FD: 424B v_exit ld bc,de 12FF: D1 pop de 1300: FDE9 jp (iy) 1302: 1302: ; ------------------------------------- 1302: ; call procedure at calculated address 1302: ;
call_calc -- 1302: 1302: v_call_calc 1302: E1 pop hl ; new top 1303: C5 push bc ; push ret addr 1304: 424B ld bc,de ; pc := top 1306: EB ex hl,de ; top := new top 1307: FDE9 jp (iy) 1309: 1309: ; ---------------------------------------- 1309: ; procedures with local variables 1309: ; 1309: ; procedure entry: 1309: ; allocate local variables on stack: 1309: ; 1309: ; penter 1309: ; tells how many variables to allocate on the stack. 1309: ; e.g. allocate 5 local variables with: penter 5. 1309: ; 1309: ; access function arguments: 1309: ; lvar 2 (last argument) 1309: ; lvar 3 (last but one argument) 1309: ; 1309: ; access local variables: 1309: ; lvar -1 (first local var) 1309: ; lvar -2 (2nd local var) 1309: ; 1309: ; access what you better don't access: 1309: ; lvar 0 old ix 1309: ; lvar 1 return address 1309: ; 1309: ; procedure exit: 1309: ; close local variables & return: 1309: ; 1309: ; pexit 1309: ; tells how many arguments to remove from stack. 1309: ; e.g. if the function took 3 arguments then exit with: pexit 3. 1309: ; 1309: ; preturn 1309: ; same as pexit, but returns a return value . 1309: 1309: ; ---------------------------------------- 1309: ; procedure entry: 1309: ; [,...] penter -- 1309: 1309: v_penter 1309: E1 pop hl ; ret addr 130A: 130A: D5 push de ; top item 130B: E5 push hl ; ret addr 130C: DDE5 push ix ; old ix 130E: 130E: DD210000 ld ix,0 1312: DD39 add ix,sp ; new ix -> old ix 1314: 1314: 0A ld a,(bc) 1315: 03 inc bc 1316: 87 add a ; x2 1317: ED44 neg 1319: 6F ld l,a 131A: 9F sbc a ; $00 for n=0 and $FF for n>0 131B: 67 ld h,a 131C: 39 add hl,sp 131D: F9 ld sp,hl 131E: 131E: D1 pop de 131F: ; note: DE wird von einem ansonsten leeren Stack gepoppt: 131F: ; DE enthält jetzt den Wert der letzten lokalen Variablen. 131F: ; Diese wird wieder mit DE überschrieben, sobald der erste Wert auf den Stack gepusht wird. 131F: ; Das ist ungefährlich, weil sich eine lokalte Variable nicht ändern kann, solange der 131F: ; Stack leer ist. Um die lokale Variable zu ändern, müssen neuer Wert und Adresse auf den 131F: ; Stack gepusht werden => derweil ist die gefährdete lokale Variable nicht mehr in DE! 131F: FDE9 jp (iy) 1321: 1321: ; ---------------------------------------- 1321: ; exit from procedure returning a value 1321: ; preturn -- 1321: 1321: v_preturn 1321: DDF9 ld sp,ix ; discard local variables 1323: DDE1 pop ix ; old ix 1325: 1325: 0A ld a,(bc) ; arguments to discard 1326: C1 pop bc ; bc = ret addr 1327: 1327: 87 add a ; bytes to discard 1328: 6F ld l,a 1329: 2600 ld h,0 ; sign extend 132B: 39 add hl,sp 132C: F9 ld sp,hl ; discard arguments 132D: 132D: ;ld de,de ; return value is already in de 132D: FDE9 jp (iy) 132F: 132F: ; ---------------------------------------- 132F: ; exit from procedure returning nothing 132F: ; pexit -- 132F: 132F: FD213513 v_pexit ld iy,pex1 1333: 18EC jr v_preturn 1335: D1 pex1 pop de 1336: C32100 jp vip_iy 1339: 1339: ; ---------------------------------------- 1339: ; Get address of local variable 1339: ; lvar --
1339: 1339: D5 v_lvar push de 133A: 0A ld a,(bc) 133B: 03 inc bc 133C: 133C: DD54 ld d,xh 133E: DD5D ld e,xl 1340: 87 add a ; x2 & cy=vz 1341: 6F ld l,a ; l=offset 1342: 9F sbc a ; sign extend 1343: 67 ld h,a ; hl=offset 1344: 19 add hl,de ; hl=ix+offset 1345: 1345: EB ex hl,de 1346: FDE9 jp (iy) 1348: 1348: ; ---------------------------------------- 1348: ; Store value in local variable 1348: ; lvar_poke -- 1348: 1348: v_lvar_poke 1348: 0A ld a,(bc) 1349: 03 inc bc 134A: 134A: DD54 ld d,xh 134C: DD5D ld e,xl 134E: 87 add a ; x2 & cy=vz 134F: 6F ld l,a ; l=offset 1350: 9F sbc a ; sign extend 1351: 67 ld h,a ; hl=offset 1352: 19 add hl,de ; hl=ix+offset 1353: 1353: D1 pop de ; de=value 1354: 73 ld (hl),e 1355: 23 inc hl 1356: 72 ld (hl),d 1357: 1357: D1 pop de 1358: FDE9 jp (iy) 135A: 135A: ; ------------------------------------- 135A: ; increment variable at given address 135A: ;
pp -- 135A: 135A: EB v_pp ex hl,de 135B: 34 inc (hl) 135C: 2002 jr nz,$+4 135E: 23 inc hl 135F: 34 inc (hl) 1360: D1 pop de ; pop de erst zum schluss, falls der stack leer ist 1361: FDE9 jp (iy) ; und pp die letzte lokale Variable incrementiert 1363: 1363: ; ------------------------------------- 1363: ; decrement variable at given address 1363: ;
mm -- 1363: 1363: EB v_mm ex hl,de 1364: 7E ld a,(hl) 1365: 35 dec (hl) 1366: A7 and a 1367: 2002 jr nz,$+4 1369: 23 inc hl 136A: 35 dec (hl) 136B: D1 pop de ; pop de erst zum schluss, falls der stack leer ist 136C: FDE9 jp (iy) ; und mm die letzte lokale Variable decrementiert 136E: 136E: ; ------------------------------------- 136E: ; increment and then peek variable at given address 136E: ;
pp_peek -- 136E: 136E: v_pp_peek 136E: EB ex hl,de 136F: 5E ld e,(hl) 1370: 23 inc hl 1371: 56 ld d,(hl) 1372: 13 inc de 1373: 72 ld (hl),d 1374: 2B dec hl 1375: 73 ld (hl),e 1376: FDE9 jp (iy) 1378: 1378: ; ------------------------------------- 1378: ; decrement and then peek variable at given address 1378: ;
mm_peek -- 1378: 1378: v_mm_peek 1378: EB ex hl,de 1379: 5E ld e,(hl) 137A: 23 inc hl 137B: 56 ld d,(hl) 137C: 1B dec de 137D: 72 ld (hl),d 137E: 2B dec hl 137F: 73 ld (hl),e 1380: FDE9 jp (iy) 1382: 1382: ; ------------------------------------- 1382: ; peek and then increment variable at given address 1382: ;
peek_pp -- 1382: 1382: v_peek_pp 1382: EB ex hl,de 1383: 5E ld e,(hl) 1384: 23 inc hl 1385: 56 ld d,(hl) 1386: 13 inc de 1387: 72 ld (hl),d 1388: 2B dec hl 1389: 73 ld (hl),e 138A: 1B dec de 138B: FDE9 jp (iy) 138D: 138D: ; ------------------------------------- 138D: ; peek and then increment variable at given address 138D: ;
peek_mm -- 138D: 138D: v_peek_mm 138D: EB ex hl,de 138E: 5E ld e,(hl) 138F: 23 inc hl 1390: 56 ld d,(hl) 1391: 1B dec de 1392: 72 ld (hl),d 1393: 2B dec hl 1394: 73 ld (hl),e 1395: 13 inc de 1396: FDE9 jp (iy) 1398: 1398: ; ------------------------------------- 1398: ; bitwise boolean and 1398: ; may be used for masking arbitrary values 1398: ; or for 'and'ing boolean values (boolean: 0 and 1 only) 1398: ; if used in a boolean sense on arbitrary values 1398: ; the result will not be as desired, 1398: ; and -- 1398: 1398: E1 v_and pop hl 1399: 7C ld a,h 139A: A2 and d 139B: 57 ld d,a 139C: 7D ld a,l 139D: A3 and e 139E: 5F ld e,a 139F: FDE9 jp (iy) 13A1: 13A1: ; ------------------------------------- 13A1: ; bitwise boolean or 13A1: ; or -- 13A1: 13A1: E1 v_or pop hl 13A2: 7C ld a,h 13A3: B2 or d 13A4: 57 ld d,a 13A5: 7D ld a,l 13A6: B3 or e 13A7: 5F ld e,a 13A8: FDE9 jp (iy) 13AA: 13AA: ; ------------------------------------- 13AA: ; bitwise boolean xor 13AA: ; or -- 13AA: 13AA: E1 v_xor pop hl 13AB: 7C ld a,h 13AC: AA xor d 13AD: 57 ld d,a 13AE: 7D ld a,l 13AF: AB xor e 13B0: 5F ld e,a 13B1: FDE9 jp (iy) 13B3: 13B3: 13B3: ; ------------------------------------- 13B3: ; Dispatcher table 13B3: ; ------------------------------------- 13B3: 13B3: FFFFFFFF 13B7: FFFFFFFF 13BB: FFFFFFFF 13BF: FFFFFFFF 13C3: FFFFFFFF 13C7: FFFFFFFF 13CB: FFFFFFFF 13CF: FFFFFFFF 13D3: FFFFFFFF 13D7: FFFFFFFF 13DB: FFFFFFFF 13DF: FFFFFFFF 13E3: FFFFFFFF 13E7: FFFFFFFF 13EB: FFFFFFFF 13EF: FFFFFFFF 13F3: FFFFFFFF 13F7: FFFFFFFF 13FB: FFFFFFFF 13FF: FF defs 255 - ($-1)%256 1400: v_tab 1400: 1400: byte equ $-v_tab 1400: C37112 jp v_byte 1403: 1403: number equ $-v_tab 1403: C37C12 jp v_number 1406: 1406: ;hpush equ $-v_tab 1406: ; jp v_hpush 1406: 1406: hpeek equ $-v_tab 1406: C35A16 jp v_hpeek 1409: 1409: ;hpop equ $-v_tab 1409: ; jp v_hpop 1409: 1409: mult equ $-v_tab 1409: C3A515 jp v_mult 140C: 140C: div equ $-v_tab 140C: C3CF15 jp v_div 140F: 140F: rem equ $-v_tab 140F: C3DE15 jp v_rem 1412: 1412: peek equ $-v_tab 1412: C38512 jp v_peek 1415: 1415: peekb equ $-v_tab 1415: C37512 jp v_peekb 1418: 1418: poke equ $-v_tab 1418: C38B12 jp v_poke 141B: 141B: pokeb equ $-v_tab 141B: C39312 jp v_pokeb 141E: 141E: jump equ $-v_tab 141E: C3CA12 jp v_jump 1421: 1421: if equ $-v_tab 1421: C35912 jp v_if 1424: 1424: iff equ $-v_tab 1424: C36012 jp v_iff 1427: 1427: ifff equ $-v_tab 1427: C36712 jp v_ifff 142A: 142A: bra equ $-v_tab 142A: C3D112 jp v_bra 142D: 142D: bra_if equ $-v_tab 142D: C3DC12 jp v_bra_if 1430: 1430: bra_ifnot equ $-v_tab 1430: C3E412 jp v_bra_ifnot 1433: 1433: call equ $-v_tab 1433: C3F312 jp v_call 1436: 1436: opcode equ $-v_tab 1436: C3EC12 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: C3FD12 jp v_jp_calc 143F: 143F: call_calc equ $-v_tab 143F: C30213 jp v_call_calc 1442: 1442: penter equ $-v_tab 1442: C30913 jp v_penter 1445: 1445: preturn equ $-v_tab 1445: C32113 jp v_preturn 1448: 1448: pexit equ $-v_tab 1448: C32F13 jp v_pexit 144B: 144B: lvar equ $-v_tab 144B: C33913 jp v_lvar 144E: 144E: lvar_poke equ $-v_tab 144E: C34813 jp v_lvar_poke 1451: 1451: pp equ $-v_tab 1451: C35A13 jp v_pp 1454: 1454: mm equ $-v_tab 1454: C36313 jp v_mm 1457: 1457: pp_peek equ $-v_tab 1457: C36E13 jp v_pp_peek 145A: 145A: mm_peek equ $-v_tab 145A: C37813 jp v_mm_peek 145D: 145D: peek_pp equ $-v_tab 145D: C38213 jp v_peek_pp 1460: 1460: peek_mm equ $-v_tab 1460: C38D13 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: C39912 jp v_over 1477: 1477: pick equ $-v_tab 1477: C39F12 jp v_pick 147A: 147A: and equ $-v_tab 147A: C39813 jp v_and 147D: 147D: or equ $-v_tab 147D: C3A113 jp v_or 1480: 1480: xor equ $-v_tab 1480: C3AA13 jp v_xor 1483: 1483: shl equ $-v_tab 1483: C32516 jp v_shl 1486: 1486: shr equ $-v_tab 1486: C33E16 jp v_shr 1489: 1489: umax equ $-v_tab 1489: C33512 jp v_umax 148C: 148C: umin equ $-v_tab 148C: C33F12 jp v_umin 148F: 148F: max equ $-v_tab 148F: C34912 jp v_max 1492: 1492: min equ $-v_tab 1492: C35112 jp v_min 1495: 1495: rnd equ $-v_tab 1495: C30316 jp v_rnd 1498: 1498: ;dealloc equ $-v_tab 1498: ; jp v_mem_dealloc 1498: 1498: string equ $-v_tab 1498: C35B10 jp v_string 149B: 149B: strlen equ $-v_tab 149B: C38110 jp v_strlen 149E: 149E: catstr equ $-v_tab 149E: C37A11 jp v_catstr 14A1: 14A1: leftstr equ $-v_tab 14A1: C30A12 jp v_leftstr 14A4: 14A4: rightstr equ $-v_tab 14A4: C31A12 jp v_rightstr 14A7: 14A7: midstr equ $-v_tab 14A7: C3E611 jp v_midstr 14AA: 14AA: substr equ $-v_tab 14AA: C3EA11 jp v_substr 14AD: 14AD: upperstr equ $-v_tab 14AD: C3BA10 jp v_upperstr 14B0: 14B0: lowerstr equ $-v_tab 14B0: C3DA10 jp v_lowerstr 14B3: 14B3: charstr equ $-v_tab 14B3: C3FA10 jp v_charstr 14B6: 14B6: hex2str equ $-v_tab 14B6: C3AA16 jp v_hex2str 14B9: 14B9: hex4str equ $-v_tab 14B9: C39C16 jp v_hex4str 14BC: 14BC: numstr equ $-v_tab 14BC: C38316 jp v_numstr 14BF: 14BF: print equ $-v_tab 14BF: C36B16 jp v_print 14C2: 14C2: printchar equ $-v_tab 14C2: C36416 jp v_printchar 14C5: 14C5: printdec equ $-v_tab 14C5: C37516 jp v_printdec 14C8: 14C8: printhex equ $-v_tab 14C8: C37C16 jp v_printhex 14CB: 14CB: bit equ $-v_tab 14CB: C37115 jp v_bit 14CE: 14CE: setbit equ $-v_tab 14CE: C3A812 jp v_setbit 14D1: 14D1: clrbit equ $-v_tab 14D1: C3B912 jp v_clrbit 14D4: 14D4: ;rol equ $-v_tab 14D4: ; jp v_rol 14D4: 14D4: ;ror equ $-v_tab 14D4: ; jp v_ror 14D4: 14D4: neg equ $-v_tab 14D4: 1B dec de 14D5: cpl equ $-v_tab 14D5: 1832 jr v_cpl 14D7: 14D7: swap equ $-v_tab 14D7: 1839 jr v_swap 14D9: 14D9: add equ $-v_tab 14D9: 183C jr v_add 14DB: 14DB: sub equ $-v_tab 14DB: 183F jr v_sub 14DD: 14DD: eq equ $-v_tab 14DD: 184F jr v_eq 14DF: 14DF: ne equ $-v_tab 14DF: 1842 jr v_ne 14E1: 14E1: gt equ $-v_tab 14E1: 1856 jr v_gt 14E3: 14E3: ge equ $-v_tab 14E3: 1866 jr v_ge 14E5: 14E5: lt equ $-v_tab 14E5: 1855 jr v_lt 14E7: 14E7: le equ $-v_tab 14E7: 185F jr v_le 14E9: 14E9: not equ $-v_tab 14E9: 186C jr v_not 14EB: 14EB: bool equ $-v_tab 14EB: 1870 jr v_bool 14ED: 14ED: getkey equ $-v_tab 14ED: 1874 jr v_getkey 14EF: 14EF: waitkey equ $-v_tab 14EF: 1877 jr v_waitkey 14F1: 14F1: abs equ $-v_tab 14F1: 1810 jr v_abs 14F3: 14F3: lvar_peek equ $-v_tab 14F3: 0A ld a,(bc) 14F4: ;inc bc 14F4: ;jr v_lvar_peek_ctd 14F4: 14F4: v_tab_end 14F4: 14F4: ; ------------------------------------- 14F4: ; Dispatcher table end 14F4: ; ------------------------------------- 14F4: 14F4: 14F4: ; ---------------------------------------- 14F4: ; peek value from local variable 14F4: ; lvar_peek -- 14F4: 14F4: v_lvar_peek_ctd 14F4: ;ld a,(bc) 14F4: 03 inc bc 14F5: 14F5: DD54 ld d,xh 14F7: DD5D ld e,xl 14F9: 87 add a ; x2 & cy=vz 14FA: 6F ld l,a ; l=offset 14FB: 9F sbc a ; sign extend 14FC: 67 ld h,a ; hl=offset 14FD: 19 add hl,de ; hl=ix+offset 14FE: 5E ld e,(hl) 14FF: 23 inc hl 1500: 56 ld d,(hl) ; peek word 1501: FDE9 jp (iy) 1503: 1503: ; ---------------------------------------- 1503: ; Convert to absolute value 1503: ; note: fails for $8000 (obviously) 1503: ; abs -- 1503: 1503: CB7C v_abs bit 7,h 1505: CA2F12 jp z,vip_dis 1508: ;jr v_neg 1508: 1508: ; ------------------------------------- 1508: ; negate arithmetic value 1508: ; note: fails for $8000 (obviously) 1508: ; neg -- 1508: 1B v_neg dec de 1509: ;jr v_cpl 1509: 1509: ; ------------------------------------- 1509: ; bitwise complement 1509: ; cpl -- 1509: 1509: 7A v_cpl ld a,d 150A: 2F cpl 150B: 57 ld d,a 150C: 7B ld a,e 150D: 2F cpl 150E: 5F ld e,a 150F: C32100 jp vip_iy ; note: v_neg wird von mul/div/rem zum Abschluss angesprungen, 1512: ; wenn das Ergebnis negativ wird: IY muss wieder restauriert werden. 1512: 1512: ; ------------------------------------- 1512: ; swap 1st and 2nd top stack data 1512: ; swap -- 1512: 1512: E1 v_swap pop hl 1513: D5 push de 1514: EB ex hl,de 1515: FDE9 jp (iy) 1517: 1517: ; ------------------------------------- 1517: ; add two values 1517: ; add -- 1517: 1517: E1 v_add pop hl 1518: 19 add hl,de 1519: EB ex hl,de 151A: FDE9 jp (iy) 151C: 151C: ; ------------------------------------- 151C: ; subtract 2nd from 1st value 151C: ; add -- 151C: 151C: E1 v_sub pop hl 151D: A7 and a 151E: ED52 vsub1 sbc hl,de 1520: EB ex hl,de 1521: FDE9 jp (iy) 1523: 1523: ; ------------------------------------- 1523: ; compare two values: true if not equal 1523: ; ne -- 1523: 1523: E1 v_ne pop hl 1524: A7 and a 1525: ED52 sbc hl,de 1527: 280B jr z,set0 1529: 110100 set1 ld de,1 152C: FDE9 jp (iy) 152E: 152E: ; ------------------------------------- 152E: ; compare two values: true if equal 152E: ; eq -- 152E: 152E: E1 v_eq pop hl 152F: A7 and a 1530: ED52 sbc hl,de 1532: 28F5 jr z,set1 1534: 110000 set0 ld de,0 1537: FDE9 jp (iy) 1539: 1539: ; ------------------------------------- 1539: ; signed compare value1 with value2: true if greater than 1539: ; gt -- 1539: 1539: E1 v_gt pop hl 153A: EB ex hl,de 153B: FE defb $fe ; cp a,N 153C: ;jr v_lt 153C: 153C: ; ------------------------------------- 153C: ; signed compare value1 with value2: true if less than 153C: ; lt -- 153C: 153C: E1 v_lt pop hl 153D: 7C ld a,h 153E: AA xor d 153F: FA5115 jp m,vge1 1542: ED52 vlt1 sbc hl,de 1544: 38E3 jr c,set1 1546: 18EC jr set0 1548: 1548: ; ------------------------------------- 1548: ; signed compare value1 with value2: true if less than or equal 1548: ; le -- 1548: 1548: E1 v_le pop hl 1549: EB ex hl,de 154A: FE defb $fe ; cp a,N 154B: 154B: ; ------------------------------------- 154B: ; signed compare value1 with value2: true if greater than or equal 154B: ; ge -- 154B: 154B: E1 v_ge pop hl 154C: 7C ld a,h 154D: AA xor d 154E: FA4215 jp m,vlt1 1551: ED52 vge1 sbc hl,de 1553: 38DF jr c,set0 1555: 18D2 jr set1 1557: 1557: ; ------------------------------------- 1557: ; negate boolean value 1557: ; may be used to force an arbitrary value to either 0 or 1 1557: ; not -- 1557: 1557: 7A v_not ld a,d 1558: B3 or e 1559: 28CE jr z,set1 155B: 18D7 jr set0 155D: 155D: ; ------------------------------------- 155D: ; make boolean value 155D: ; may be used to force an arbitrary value to either 0 or 1 155D: ; bool -- 155D: 155D: 7A v_bool ld a,d 155E: B3 or e 155F: 28D3 jr z,set0 1561: 18C6 jr set1 1563: 1563: ; ------------------------------------- 1563: ; test and get character code from the keyboard. 1563: ; returns 0 if no key available. 1563: ; getkey -- 1563: 1563: v_getkey 1563: CDE619 call get_inkey 1566: 1803 jr vwk1 1568: 1568: ; ------------------------------------- 1568: ; wait for and get character code from the keyboard. 1568: ; waitkey -- 1568: 1568: v_waitkey 1568: CDCF19 call wait_inkey 156B: D5 vwk1 push de 156C: 5F ld e,a 156D: 1600 ld d,0 156F: FDE9 jp (iy) 1571: 1571: ; ------------------------------------- 1571: ; get bit [15=left..0=right] 1571: ; bit -- 1571: 1571: E1 v_bit pop hl ; hl=value; de=index 1572: 7B ld a,e 1573: E6F0 and $f0 1575: B2 or d 1576: 20BC jr nz,set0 ; return 0 if out of range 1578: 1578: 7B ld a,e 1579: CD791F call calc_bmask 157C: CB5B bit 3,e 157E: 2801 jr z,vb1 1580: 6C ld l,h 1581: A5 vb1 and l 1582: 28B0 jr z,set0 1584: 18A3 jr set1 1586: 1586: ; ------------------------------------- 1586: ; UP: negate negative numbers in hl and de 1586: ; preset IY with v_neg if DE xor HL neg. 1586: 1586: ;up_vz_mult: 1586: ; ld a,h 1586: ; and d 1586: ; ret p 1586: 1586: up_vz_mult_quick 1586: 7C ld a,h 1587: AA xor d 1588: F28F15 jp p,upvz1 158B: FD210815 ld iy,v_neg ; Ergebnis wird negativ -> exit via v_neg 158F: 158F: CB7C upvz1 bit 7,h 1591: 2807 jr z,abs_de 1593: 1593: 2B dec hl 1594: 7C ld a,h 1595: 2F cpl 1596: 67 ld h,a 1597: 7D ld a,l 1598: 2F cpl 1599: 6F ld l,a 159A: 159A: CB7A abs_de bit 7,d 159C: C8 ret z 159D: 159D: 1B neg_de dec de 159E: 7A ld a,d 159F: 2F cpl 15A0: 57 ld d,a 15A1: 7B ld a,e 15A2: 2F cpl 15A3: 5F ld e,a 15A4: C9 ret 15A5: 15A5: 15A5: ; ------------------------------------- 15A5: ; Signed multiplication 15A5: ; Multiplikation DE = HL x DE 15A5: ; mult -- 15A5: 15A5: E1 v_mult pop hl 15A6: C5 push bc 15A7: 15A7: 7C ld a,h 15A8: B2 or d 15A9: FC8615 call m,up_vz_mult_quick 15AC: 15AC: 7C ld a,h ; Sortiere: DE ≤ HL 15AD: BA cp d 15AE: 2002 jr nz,$+4 15B0: 7D ld a,l 15B1: BB cp e 15B2: 3001 jr nc,$+3 15B4: EB ex hl,de ; HL = Multiplikand 15B5: 4A ld c,d ; CA = Multiplikator 15B6: 7B ld a,e 15B7: 110000 ld de,0 ; Ergebnissammler 15BA: 180A jr m1 15BC: 15BC: ; Multiplikand links schieben 15BC: 29 m2 add hl,hl 15BD: ; Multiplikator rechts schieben 15BD: CB39 m3 srl c 15BF: 1F rra 15C0: 30FA jr nc,m2 15C2: ; Bit=1 => Multiplikand addieren 15C2: EB ex hl,de 15C3: 19 add hl,de 15C4: EB ex hl,de 15C5: ; Multiplikand links schieben 15C5: 29 add hl,hl 15C6: ; Schleifenendtest 15C6: A7 m1 and a 15C7: 20F4 jr nz,m3 15C9: B9 cp c 15CA: 20F1 jr nz,m3 15CC: C1 pop bc 15CD: FDE9 jp (iy) 15CF: 15CF: ; ------------------------------------- 15CF: ; Signed division 15CF: ; div -- 15CF: 15CF: E1 v_div pop hl 15D0: C5 push bc 15D1: 15D1: 7C ld a,h 15D2: B2 or d 15D3: FC8615 call m,up_vz_mult_quick 15D6: 15D6: CDEC15 vd3 call div_hl_de 15D9: 5059 ld de,bc 15DB: C1 pop bc 15DC: FDE9 jp (iy) 15DE: 15DE: ; ------------------------------------- 15DE: ; Signed division remainder 15DE: ; The remainder has the same sign as the division result. 15DE: ; so that n1 / n2 = quot rem r <=> n1/n2-quot = remainder 15DE: ; rem -- 15DE: 15DE: E1 v_rem pop hl 15DF: C5 push bc 15E0: 15E0: 7C ld a,h 15E1: B2 or d 15E2: FC8615 call m,up_vz_mult_quick 15E5: 15E5: CDEC15 vr1 call div_hl_de 15E8: EB ex hl,de 15E9: C1 pop bc 15EA: FDE9 jp (iy) 15EC: 15EC: div_hl_de ; bc rem hl = hl / de 15EC: 3E10 ld a,16 15EE: 444D ld bc,hl 15F0: 210000 ld hl,0 ; hlbc := hl 15F3: 15F3: CB31 div2 sll c ; c := 2*c+1 15F5: CB10 rl b ; bc := 2*bc+1 15F7: ED6A adc hl,hl ; hlbc := 2*hlbc+1 15F9: 15F9: ED52 sbc hl,de ; subtract (test) 15FB: 3002 jr nc,div1 ; worked! 15FD: 0D dec c ; else clear bit 0 of result 15FE: 19 add hl,de ; and undo sub 15FF: 3D div1 dec a 1600: 20F1 jr nz,div2 1602: C9 ret ; hl := rem; bc := quot 1603: 1603: 1603: ; ------------------------------------- 1603: ; Random Number 1603: ; Benutzt den Schieberegister-Algorithmus des AY-Soundchips 1603: ; 1603: ; ehl formen ein Shiftregister ((17 Bit)) 1603: ; ehl' = ehl<<1 + ( ehl.bit(16) ^ ehl.bit(14) ) 1603: ; 1603: ; rnd -- 1603: 1603: rnd_seed data 3 1603: 1603: 2A2B5B v_rnd ld hl,(rnd_seed) 1606: 3A2D5B ld a,(rnd_seed+2) 1609: 5F ld e,a ; seed = ehl ((lower 17 bit)) 160A: 160A: 1610 ld d,16 ; generate 16 new bits 160C: 160C: ; calculate 1 bit: 160C: 7C rnd1 ld a,h 160D: CB07 rlc a 160F: CB07 rlc a 1611: AB xor e 1612: CB0F rrc a ; cy = neues bit 1614: 1614: ED6A adc hl,hl ; shift ehl left, padding new bit 1616: CB13 rl e 1618: 1618: 15 dec d 1619: 20F1 jr nz,rnd1 ; next bit 161B: 161B: ; hl = seed = result 161B: 222B5B ld (rnd_seed),hl 161E: 7B ld a,e 161F: 322D5B ld (rnd_seed+2),a 1622: 1622: EB ex hl,de ; de = result 1623: FDE9 jp (iy) 1625: 1625: #if 0 1625: ; ---------------------------------------- 1625: ; rotate right 1625: ; ror -- 1625: 1625: v_ror pop hl ; ror -- 1625: ld a,e 1625: bit 3,a 1625: jr z,vror4 1625: 1625: ld d,h ; einmal 8 Rotationen en block 1625: ld h,l 1625: ld l,d 1625: 1625: vror4 and $07 1625: jr z,vror3 1625: ld e,a ; e=count 1625: sub a ; a=right cy collector 1625: 1625: vror2 srl h 1625: rr l 1625: rra 1625: 1625: dec e 1625: jr nz,vror2 1625: 1625: or a,h 1625: ld h,a 1625: 1625: vror3 ex hl,de 1625: jp (iy) 1625: 1625: ; ---------------------------------------- 1625: ; rotate left 1625: ; rol -- 1625: 1625: v_rol pop hl ; rol -- 1625: ld a,e 1625: bit 3,a 1625: jr z,vrol4 1625: 1625: ld d,h ; einmal 8 Rotationen en block 1625: ld h,l 1625: ld l,d 1625: 1625: vrol4 and $07 1625: jr z,vrol3 1625: ld e,a ; e=count 1625: sub a ; a=left cy collector 1625: 1625: vrol2 add hl,hl 1625: rla 1625: 1625: dec e 1625: jr nz,vrol2 1625: 1625: or a,l 1625: ld l,a 1625: 1625: vrol3 ex hl,de 1625: jp (iy) 1625: #endif 1625: 1625: ; ---------------------------------------- 1625: ; shift left 1625: ; shl -- 1625: 1625: E1 v_shl pop hl 1626: 7B ld a,e 1627: FE10 cp 16 1629: D23415 jp nc,set0 162C: CB5F bit 3,a 162E: 2803 jr z,vshl4 1630: 1630: 65 ld h,l ; einmal 8 Rotationen en block 1631: 2E00 ld l,0 1633: 1633: E607 vshl4 and $07 1635: 2804 jr z,vshl3 1637: 1637: 29 vshl2 add hl,hl 1638: 1638: 3D dec a 1639: 20FC jr nz,vshl2 163B: 163B: EB vshl3 ex hl,de 163C: FDE9 jp (iy) 163E: 163E: ; ---------------------------------------- 163E: ; shift right 163E: ; shr -- 163E: 163E: E1 v_shr pop hl 163F: 7B ld a,e 1640: FE10 cp 16 1642: D23415 jp nc,set0 1645: CB5F bit 3,a 1647: 2803 jr z,vshr4 1649: 1649: 6C ld l,h ; einmal 8 Rotationen en block 164A: 2600 ld h,0 164C: 164C: E607 vshr4 and $07 164E: 2807 jr z,vshr3 1650: 1650: CB3C vshr2 srl h 1652: CB1D rr l 1654: 1654: 3D dec a 1655: 20F9 jr nz,vshr2 1657: 1657: EB vshr3 ex hl,de 1658: FDE9 jp (iy) 165A: 165A: #if 0 165A: ; ------------------------------------- 165A: ; push value on heap 165A: ; hpush -- 165A: 165A: v_hpush ld hl,(hp) 165A: ld (hl),e 165A: inc hl 165A: ld (hl),d 165A: inc hl 165A: ld (hp),hl 165A: pop de 165A: jp (iy) 165A: #endif 165A: 165A: #if 0 165A: ; ------------------------------------- 165A: ; pop value from heap 165A: ; hpop -- 165A: 165A: v_hpop push de 165A: ld hl,(hp) 165A: dec hl 165A: ld d,(hl) 165A: dec hl 165A: ld e,(hl) 165A: ld (hp),hl 165A: jp (iy) 165A: #endif 165A: 165A: ; ------------------------------------- 165A: ; peek top value on heap 165A: ; hpeek -- 165A: 165A: D5 v_hpeek push de 165B: 2A215B ld hl,(mem_heap_ptr) 165E: 2B dec hl 165F: 56 ld d,(hl) 1660: 2B dec hl 1661: 5E ld e,(hl) 1662: FDE9 jp (iy) 1664: 1664: 1664: ; ------------------------------------- 1664: ; print single character 1664: ; printchar -- 1664: 1664: v_printchar 1664: 7B ld a,e 1665: CDBC04 call print_char 1668: D1 pop de 1669: FDE9 jp (iy) 166B: 166B: ; ------------------------------------- 166B: ; print immediate text 166B: ; print "text\0" -- 166B: 166B: 6069 v_print ld hl,bc 166D: CDC204 call print_text_hl 1670: 444D ld bc,hl 1672: 03 inc bc 1673: FDE9 jp (iy) 1675: 1675: ; ------------------------------------- 1675: ; print value as signed decimal number 1675: ; printdec -- 1675: 1675: v_printdec 1675: EB ex hl,de 1676: CD5804 call print_vz_dec 1679: D1 pop de 167A: FDE9 jp (iy) 167C: 167C: ; ------------------------------------- 167C: ; print value as unsigned 4-letter hexadecimal number 167C: ; printhex -- 167C: 167C: v_printhex 167C: EB ex hl,de 167D: CD6104 call print_hex4 1680: D1 pop de 1681: FDE9 jp (iy) 1683: 1683: ; ------------------------------------- 1683: ; convert value to signed decimal string 1683: ; numstr -- 1683: 1683: v_numstr 1683: C5 push bc 1684: EB ex hl,de ; hl=value 1685: 11255B ld de,v_scratch ; de->buffer 1688: CDBA1E call vzdecstr ; de++ 168B: 21DBA4 ld hl,-v_scratch 168E: 19 add hl,de ; hl=text size 168F: 444D ld bc,hl ; bc=size 1691: 1691: CDDA0F call mem_alloc ; bc=size; de->data; hl=handle 1694: E5 push hl ; bc=size; de->data; sp:handle 1695: 21255B ld hl,v_scratch 1698: EDB0 ldir 169A: 181B jr vhx2 169C: 169C: ; ------------------------------------- 169C: ; convert value to unsigned 4-letter hexadecimal string 169C: ; -- 169C: 169C: v_hex4str 169C: C5 push bc 169D: D5 push de 169E: 010400 ld bc,4 16A1: CDDA0F call mem_alloc ; bc=len; de->data; hl=handle 16A4: E3 ex hl,(sp) ; bc=len; de->data; hl=value; sp:handle 16A5: CD161F call hexstr4 16A8: 180D jr vhx2 16AA: 16AA: ; ------------------------------------- 16AA: ; convert value to unsigned 2-letter hexadecimal string 16AA: ; -- 16AA: 16AA: v_hex2str 16AA: C5 push bc 16AB: D5 push de 16AC: 010200 ld bc,2 16AF: CDDA0F call mem_alloc ; bc=len; de->data; hl=handle 16B2: E3 ex hl,(sp) ; bc=len; de->data; hl=value; sp:handle 16B3: 7D ld a,l 16B4: CD1D1F call hexstr2 16B7: D1 vhx2 pop de ; handle 16B8: C1 pop bc 16B9: FDE9 jp (iy) 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: #if 0 16BB: 16BB: ; -------------------------------------- 16BB: ; Edit text 16BB: 16BB: 16BB: ; 16BB: ; in: B,C = top left corner of box 16BB: ; D,E = rows/cols; D=1 16BB: ; HL -> text 16BB: ; out: HL -> text 16BB: ; mod: 16BB: 16BB: edit_text: ; edittext -- 16BB: 16BB: ed_text equ 5 16BB: ed_top equ 4 16BB: ed_left equ 3 16BB: ed_width equ 2 16BB: ed_key equ -1 16BB: ed_pos equ -2 16BB: 16BB: db penter, 2 16BB: db lvar_peek, ed_text, strlen, lvar_poke, ed_pos 16BB: 16BB: ; print current text with cursor 16BB: edtxt0 db lvar_peek, ed_top 16BB: db lvar_peek, ed_left 16BB: db opcode, v_locate%256, v_locate/256 16BB: db lvar_peek, ed_width 16BB: db opcode, v_clear_cols%256, v_clear_cols/256 16BB: db lvar_peek, ed_text, lvar_peek, ed_pos, leftstr, printstr 16BB: db byte, charcode_icursor, printchar 16BB: db lvar_peek, ed_text, lvar_peek, ed_pos, byte, 99, midstr, printstr 16BB: 16BB: ; wait for key 16BB: db waitkey 16BB: db dup, lvar_poke, ed_key 16BB: db byte, ' ', lt 16BB: db iff, bra, edtxt1-$ 16BB: 16BB: ; printable character 16BB: db lvar_peek, ed_text, lvar_peek, ed_pos, leftstr 16BB: db lvar_peek, ed_key, charstr, catstr 16BB: db lvar_peek, ed_text, lvar_peek, ed_pos, byte, 99, midstr, catstr 16BB: db lvar_poke, ed_text 16BB: db bra, edtxt0-$ 16BB: 16BB: ; control code 16BB: edtxt1 db lvar_peek, ed_key 16BB: db dup, keycode_left, eq ; crsr left? 16BB: db iff, bra, edtxt2-$ 16BB: db dup, keycode_right, eq ; crsr right? 16BB: db iff, bra, edtxt3-$ 16BB: db dup, keycode_return, eq ; enter? 16BB: db iff, bra, edtxt4-$ 16BB: db bra, edtxt0-$ ; else ignore 16BB: 16BB: ; cursor left 16BB: edtxt2 db drop 16BB: db lvar_peek, ed_pos, decr, byte, 0, max, lvar_poke, ed_pos 16BB: db bra, edtxt0-$ 16BB: 16BB: ; cursor right 16BB: edtxt3 db drop 16BB: db lvar_peek, ed_pos, incr, lvar_peek, ed_text, strlen, min, lvar_poke, ed_pos 16BB: db bra, edtxt0-$ 16BB: 16BB: ; enter 16BB: edtxt4 db drop 16BB: db lvar_peek, ed_top, lvar_peek, ed_left, opcode, v_locate%256, v_locate/256 16BB: db lvar_peek, ed_width, opcode, v_clear_cols%256, v_clear_cols/256 16BB: db lvar_peek, ed_text, printstr 16BB: 16BB: db lvar_peek, ed_text, preturn, 4 16BB: 16BB: #endif 16BB: 16BB: 16BB: 16BB: #include "vip.ass" 16BB: vip_end equ $ 16BB: 16BB: 16BB: 16BB: 16BB: 16BB: ; -------------------------------------------------- 16BB: ; RAM testen und löschen 16BB: ; 16BB: ; Testet und löscht das gesamte RAM mit $00. 16BB: ; 16BB: ; Wenn die unteren 16k RAM nicht fehlerfrei sind, kehrt ram_test nicht zurück 16BB: ; sondern sendet einen Fehlercode mittels Borderflashing. (TODO) 16BB: ; Aktuell signalisiert Border rot defektes RAM oder defekte Datenleitungen 16BB: ; und Border magenta defekte Adressleitungen. 16BB: ; 16BB: ; ram_test sollte defekte Bits, defekte Bausteine, den Totalausfall des RAMs, 16BB: ; defekte Datenleitungen und defekte Adressleitungen erkennen. 16BB: ; 16BB: ; Interrupts müssen selbstverständlich gesperrt sein. 16BB: ; ram_test benutzt und setzt den Stackpointer sp nicht. 16BB: ; 16BB: ; in: iy = return address 16BB: ; interrupts disabled 16BB: ; out: hl = ramtop = pointer behind usable ram; e.g. $8000 (16k) or $0000 (48k) 16BB: ; mod: af,bc,de,hl 16BB: 16BB: 16BB: ram_test: 16BB: 16BB: ; Gesamten Speicher byteweise prüfen 16BB: ; 8x single bit 1 and 8x single bit 0 16BB: 16BB: 3E80 ld a,$80 ; a = pattern = $7F = %10000000 16BD: 210040 ld hl,$4000 16C0: 16C0: 2F cs1 cpl 16C1: 77 ld (hl),a 16C2: BE cp (hl) 16C3: 200B jr nz,cs2 16C5: 16C5: 2F cpl 16C6: 77 ld (hl),a 16C7: BE cp (hl) 16C8: 2006 jr nz,cs2 16CA: 16CA: 0F rrca 16CB: 30F3 jr nc,cs1 ; same byte, next bit 16CD: 23 inc hl 16CE: 18F0 jr cs1 ; next byte; Abbruch durch defekte Zelle oder ROM 16D0: 16D0: 2B cs2 dec hl ; hl = RAMTOP -1 16D1: 7C ld a,h 16D2: FE7F cp $7F 16D4: 381C jr c,ram_broken_1 ; weniger als 16k 16D6: 16D6: ; hl = RAMTOP -1 ($7FFF oder $FFFF) 16D6: ; RAM = $01 16D6: 16D6: ; Auf Faltung (defekte Adressleitungen) prüfen und RAM löschen: 16D6: 16D6: 545D ld de,hl ; de = RAMTOP -1 16D8: 21FF3F ld hl,$3FFF ; hl = pointer = $4000 -1 16DB: 16DB: 23 cs3 inc hl 16DC: 35 dec (hl) ; $01 -> $00 16DD: 28FC jr z,cs3 ; Abbruch bei gespiegelter Zelle oder ROM 16DF: AF xor a ; a = 0 & nc 16E0: 77 ld (hl),a ; falls Abbruch wg. inc(hl)!=0 dann die gespiegelte Zelle nullen 16E1: 2B dec hl ; hl = RAMTOP -1 16E2: 16E2: ; hl = new RAMTOP -1, de = old RAMTOP -1 16E2: ; RAM = $00 16E2: 16E2: ED52 sbc hl,de 16E4: EB ex hl,de 16E5: 3801 jr c,cs5 16E7: 19 add hl,de ; hl = RAMTOP -1 = min(old RAMTOP -1, new RAMTOP -1) 16E8: 16E8: 7C cs5 ld a,h 16E9: FE7F cp $7F 16EB: 380B jr c,ram_broken_2 ; weniger als 16k 16ED: 16ED: ; Set RAMTOP and Stack 16ED: 23 inc hl ; hl = RAMTOP 16EE: CB85 res 0,l ; force even 16F0: 16F0: FDE9 jp (iy) ; return 16F2: 16F2: 16F2: 16F2: 16F2: 16F2: ; in: hl = RAMTOP-1 16F2: ; wenn hl+1==$4000 16F2: ; dann ist gar kein RAM nutzbar: 16F2: ; RAM komplett ausgefallen (Hilfsspannungen fehlen) 16F2: ; Einzelne RAM-Chips sind komplett ausgefallen 16F2: ; Problem mit Datenleitungen: Bit always 0, always 1, shortened 16F2: ; sonst sind nur einzelne Zellen der low 16k defekt 16F2: 16F2: ram_broken_1: 16F2: 3E02 ld a,red ; border 16F4: D3FE out ($FE),a 16F6: 18FE jr $ 16F8: 16F8: ; in: hl = RAMTOP-1 16F8: ; wenn hl+1<$8000 16F8: ; dann gibt es ein Problem bei den Adressleitungen auf dem ULA Bus oder Z80 Bus 16F8: ; sonst Adressleitungsproblem auf Z80 Bus 16F8: ram_broken_2: 16F8: 3E03 ld a,magenta ; border 16FA: D3FE out ($FE),a 16FC: 18FE jr $ 16FE: 16FE: 16FE: #include "ram test.ass" 16FE: 16FE: 16FE: ; --------------------------------------------- 16FE: ; E R R O R H A N D L I N G 16FE: ; --------------------------------------------- 16FE: 16FE: 16FE: ; -------------------------------------------------------- 16FE: ; Initialisierung 16FE: ; 16FE: ; in: -- 16FE: ; out: -- 16FE: ; mod: -- 16FE: 16FE: init_errors: 16FE: 219917 ld hl,oomem_handler 1701: C33117 jp set_error_handler 1704: 1704: 1704: 1704: errno data 1 1704: error_msg_handle data 2 ; handle, if errno = error_message 1704: error_handler data 2 1704: 1704: 1704: noerror equ 0 1704: error_message equ 1 ; message handle in error_msg 1704: error_oomem equ 2 1704: error_notester equ 3 1704: 1704: ; matching messages: 1704: 1704: 00 error_messages defb 0 ; 0 = no error 1705: 00 defb 0 ; 1 = custom error message 1706: 4F757420 170A: 6F66206D 170E: 656D6F72 1712: 792E00 defm "Out of memory.",0 ; 2 1715: 54657374 1719: 6572206E 171D: 6F742066 1721: 6F756E64 1725: 2E00 defm "Tester not found.",0 ; 3 1727: 00 defb 0 ; stopper 1728: 1728: 1728: ; -------------------------------------------------------- 1728: ; abort with out-of-memory 1728: ; 1728: abort_oomem: 1728: 3E02 ld a,error_oomem 172A: ;jr abort 172A: 172A: 172A: 172A: ; -------------------------------------------------------- 172A: ; Set errno and jump to memory error handler. 172A: ; If no error handler was defined, then it restarts the computer. 172A: ; does not return 172A: ; 172A: ; in: a = error number 172A: ; out: -- 172A: ; mod: does not return 172A: 172A: abort: 172A: 322E5B ld (errno),a 172D: 2A315B ld hl,(error_handler) 1730: E9 jp (hl) 1731: 1731: 1731: 1731: ; --------------------------------------- 1731: ; Set error handler 1731: ; 1731: ; in: hl = new handler 1731: ; out: -- 1731: ; mod: -- 1731: 1731: set_error_handler: 1731: 22315B ld (error_handler),hl 1734: C9 ret 1735: 1735: 1735: 1735: ; --------------------------------------- 1735: ; Get error handler 1735: ; 1735: ; in: -- 1735: ; out: hl = current handler 1735: ; mod: -- 1735: 1735: get_error_handler: 1735: 2A315B ld hl,(error_handler) 1738: C9 ret 1739: 1739: 1739: 1739: 1739: 1739: ; ------------------------------- 1739: ; set custom error message 1739: ; 1739: ; in: hl->0-terminated message 1739: ; out: hl->Kopie des Meldungstextes 1739: ; mod: af, hl 1739: 1739: set_error_message: 1739: D5 push de 173A: C5 push bc 173B: 173B: 3E01 ld a,error_message 173D: 322E5B ld (errno),a 1740: 545D ld de,hl 1742: 97 sub a 1743: 1743: BE sem1 cp (hl) 1744: 23 inc hl 1745: 20FC jr nz,sem1 1747: 1747: ED52 sbc hl,de 1749: EB ex hl,de ; hl -> message (again) 174A: 424B ld bc,de ; bc = size 174C: 174C: CD0710 call mem_save_data 174F: 222F5B ld (error_msg_handle),hl 1752: EB ex hl,de ; hl -> data 1753: 1753: C1 pop bc 1754: D1 pop de 1755: C9 ret 1756: 1756: 1756: 1756: ; -------------------------------------------------------- 1756: ; Fehlermeldung ausgeben, falls vorhanden 1756: ; 1756: ; in: -- 1756: ; out: -- 1756: ; mod: af 1756: 1756: print_error_message: 1756: 1756: 3A2E5B ld a,(errno) 1759: A7 and a 175A: C8 ret z ; no error 175B: 175B: D7 rst save_registers 175C: 175C: FE01 cp error_message ; custom message ? 175E: 200E jr nz,pem1 ; no 1760: 1760: ; error message on heap: 1760: 2A2F5B ld hl,(error_msg_handle) 1763: E5 push hl 1764: CD4D0F call mem_get_address 1767: CD7917 call up_show_error 176A: E1 pop hl 176B: C31910 jp mem_dealloc 176E: 176E: 210417 pem1 ld hl,error_messages 1771: 47 ld b,a ; b = counter = error no. 1772: AF xor a ; a = 0 1773: 1773: BE pem2 cp (hl) 1774: 23 inc hl 1775: 20FC jr nz,pem2 ; not 0 1777: 10FA djnz pem2 ; 0 found, count down msg.no. 1779: 1779: ; hl -> message 1779: up_show_error: 1779: 3E57 ld a,red_paper+bright+white 177B: 011408 ld bc,8*256+20 ; bc = rows,cols 177E: CD3E18 call open_alert ; de = top,left 1781: CDAB18 call alert_set_main_text 1784: 3E47 ld a,black_paper+white+bright 1786: 320F5B ld (print_attr),a 1789: 210D18 ld hl,msg_presskey 178C: CD0519 call alert_add_button 178F: 178F: AF xor a 1790: 322E5B ld (errno),a ; clear errno 1793: 1793: CDCF19 call wait_inkey 1796: C33D19 jp close_alert 1799: 1799: 1799: 1799: 1799: 1799: 1799: 1799: oomem_handler: 1799: ED7B005B ld sp,(RAMTOP) ; reset stack 179D: CDA20E call mem_compact 17A0: 17A0: 212E5B ld hl,errno 17A3: 3E02 ld a,error_oomem 17A5: BE cp (hl) 17A6: 77 ld (hl),a 17A7: C2BE00 jp nz,main_menu ; not re-issued => proceed. main_menu will display error. 17AA: 17AA: ; oomem in oomem processing 17AA: CDCC03 oo_oo call print_reset 17AD: CF rst print_msg 17AE: 010617 defm ctl_home,ctl_setattr,red_paper+white 17B1: 1A536576 17B5: 65726520 17B9: 6D656D6F 17BD: 72792073 17C1: 686F7274 17C5: 6167652E 17C9: 0D defm ctl_clr2eol,"Severe memory shortage.", $0d 17CA: 1A547279 17CE: 20746F20 17D2: 73617665 17D6: 20287768 17DA: 61746576 17DE: 65722920 17E2: 616E6420 17E6: 72657365 17EA: 742E0D defm ctl_clr2eol,"Try to save (whatever) and reset.", $0d 17ED: 1A507265 17F1: 7373206B 17F5: 65792066 17F9: 6F72206D 17FD: 61696E20 1801: 6D656E75 1805: 2E00 defm ctl_clr2eol,"Press key for main menu.", 0 1807: CDCF19 call wait_inkey 180A: C3BE00 jp main_menu 180D: 180D: 180D: 180D: 180D: 180D: #include "errors.ass" 180D: 180D: 180D: 180D: ; -------------------------------------------------- 180D: ; ERRORS, ALERTS & REQUESTER 180D: ; -------------------------------------------------- 180D: 180D: ; all measurement is in 8x8 character cells 180D: 180D: 180D: 20707265 1811: 73732061 1815: 6E79206B 1819: 65792000 msg_presskey: defm " press any key ",0 181D: 206F6B20 1821: 00 msg_ok: defm " ok ",0 1822: 20796573 1826: 2000 msg_yes: defm " yes ",0 1828: 206E6F20 182C: 00 msg_no: defm " no ",0 182D: 2063616E 1831: 63656C20 1835: 00 msg_cancel: defm " cancel ",0 1836: 20454E54 183A: 45522000 msg_enter: defm " ENTER ",0 183E: 183E: 183E: ; open_alert A BC -- BC DE 183E: ; alert_set_main_text BC DE HL -- BC DE 183E: ; alert_add_button BC DE HL -- BC DE 183E: ; close_alert -- 183E: 183E: 183E: 183E: 183E: 183E: ; -------------------------------------------------- 183E: ; Open Alert Box 183E: ; 183E: ; Calculate x/y position for alert 183E: ; Saves attributes on heap -> IX 183E: ; Saves pixels of main text area on heap -> IX 183E: ; Draws new box with attributes only 183E: ; sets print attribute for subsequent alert text printing 183E: ; 183E: ; note: flashing geht da nicht... 183E: ; 183E: ; in: B = rows (char cells) [1..23] 183E: ; C = columns (char cells) [2..30] 183E: ; A = attribute no flashing! 183E: ; out: D/E = top row/left column of usable area 183E: ; B/C = rows/cols of usable area for main text + buttons 183E: ; mod: AF, BC, DE 183E: 183E: open_alert: 183E: E5 push hl ; preserve 183F: C5 push bc ; alertbox.rows/cols 1840: 1840: 320F5B ld (print_attr),a 1843: 1843: ; calc clear color 1843: E6F8 and $F8 1845: 5F ld e,a ; e = attribut ohne pen bits 1846: 1F rra 1847: 1F rra 1848: 1F rra 1849: E607 and 7 ; a = paper bits moved to pen position 184B: B3 or e ; a = attr mit pen == paper 184C: F5 push af ; attr 184D: 184D: C5 push bc ; sp: width, height 184E: 184E: ; calc location for top/left corner: 184E: 3E18 ld a,24 ; screen height 1850: 90 sub b ; remaining rows 1851: 47 ld b,a 1852: 87 add a 1853: 87 add a 1854: 80 add b ; rem.rows*5 1855: 0F rrca 1856: 0F rrca 1857: 0F rrca 1858: 0F rrca 1859: E60F and $f ; rem.rows*5/16 ~ 1/3 185B: 47 ld b,a ; b = top row 185C: 185C: 3E20 ld a,32 ; screen width 185E: 91 sub c 185F: 1F rra 1860: 4F ld c,a ; c = left column 1861: 1861: ; save attr bytes 1861: CD390E call calc_attr_hl_for_row_b_col_c ; -> hl 1864: 5059 ld de,bc ; de = row/col of top/left corner 1866: C1 pop bc ; bc = height,width 1867: 04 inc b ; +1 for shadow 1868: 0C inc c ; +1 for shadow 1869: E5 push hl 186A: CD030D call scr_save_attributes ; save attributes on heap 186D: E1 pop hl 186E: 05 dec b ; undo +1 186F: 0D dec c ; undo +1 1870: 1870: ; clear attr box: 1870: F1 pop af ; a = attr 1871: CD640C call clear_attributes 1874: 1874: ; draw drop shadow: 1874: D5 push de ; sp: row/col of top/left corner 1875: 1875: 59 ld e,c ; width 1876: 1600 ld d,0 1878: 19 add hl,de ; hl -> right beyond top/right corner 1879: 1E20 ld e,32 ; de = 32 = offset/row 187B: ;ld b,b ; b = rows 187B: 19 oa1 add hl,de ; step down 187C: CBB6 res 6,(hl) ; clear bright bit 187E: 10FB djnz oa1 1880: ; now hl -> right/left beyond bottom/right corner of box 1880: 41 ld b,c ; b = cols 1881: CBB6 oa2 res 6,(hl) ; clear bright bit 1883: 2B dec hl 1884: 10FB djnz oa2 1886: 1886: D1 pop de ; de = row/col of top/left corner 1887: C1 pop bc ; bc = rows/cols 1888: E1 pop hl ; hl 1889: 1889: ; adjust box.top/left and box.rows/cols 1889: ; to cover usable for main text only. 1889: 14 inc d ; top += 2 188A: 14 inc d 188B: 188B: 1C inc e ; left += 2 188C: 1C inc e 188D: 188D: 78 ld a,b 188E: D605 sub 5 1890: 47 ld b,a ; rows -= 5 = 2 top, 1 below, 1 buttons, 1 below 1891: 1891: 79 ld a,c ; cols -= 4 = 2 left, r right 1892: D604 sub 4 1894: 4F ld c,a 1895: 1895: CD9B18 call alert_save_pixels ; main text area pixels 1898: 1898: 04 inc b ; add 2 rows to include the buttons row 1899: 04 inc b 189A: C9 ret 189B: 189B: 189B: 189B: ; -------------------------------------------------- 189B: ; Save pixels of text area 189B: ; 189B: ; in: de = top/left corner 189B: ; bc = rows/cols 189B: ; out: -- 189B: ; mod: af, iy 189B: 189B: alert_save_pixels: 189B: D7 rst save_registers 189C: C5 push bc ; size 189D: 424B ld bc,de ; loc 189F: CD480E call calc_pixel_hl_for_row_b_col_c 18A2: C1 pop bc 18A3: E5 push hl 18A4: CDD20C call scr_save_pixels ; save pixels on heap 18A7: E1 pop hl 18A8: C3460C jp clear_pixels_quick 18AB: 18AB: 18AB: 18AB: ; -------------------------------------------------- 18AB: ; Add text to alert box 18AB: ; 18AB: ; in: hl -> text, delimited with 0-byte 18AB: ; de = top/left corner of usable area for main text 18AB: ; bc = rows/cols of usable area for main text + buttons 18AB: ; out: -- 18AB: ; mod: af 18AB: 18AB: alert_set_main_text: 18AB: D7 rst save_registers 18AC: 18AC: 05 dec b ; subtract the buttons area 18AD: 05 dec b 18AE: C8 ret z ; bu hu 18AF: 18AF: 7B ld a,e ; cell col -> pixel col 18B0: 87 add a 18B1: 87 add a 18B2: 87 add a 18B3: 5F ld e,a 18B4: 18B4: 79 ld a,c ; cell col -> pixel col 18B5: 87 add a 18B6: 87 add a 18B7: 87 add a 18B8: 4F ld c,a 18B9: 18B9: C5 absmt1 push bc 18BA: D5 push de 18BB: CDED18 call up_print_some_text 18BE: D1 pop de 18BF: C1 pop bc 18C0: 18C0: 7E absmt5 ld a,(hl) 18C1: A7 and a 18C2: C8 ret z ; end of text reached => exit 18C3: FE20 cp ' ' 18C5: 3809 jr c,absmt4 ; control code 18C7: 23 inc hl 18C8: 28F6 jr z,absmt5 ; skip space(s) 18CA: 2B dec hl 18CB: 18CB: ; text wraps => resume with next row 18CB: 14 absmt2 inc d ; top row++ 18CC: 05 dec b ; rows-- 18CD: 20EA jr nz,absmt1 18CF: C9 ret ; out of space 18D0: 18D0: ; break at control code: 18D0: CDBC04 absmt4 call print_char ; print the control code 18D3: 23 inc hl 18D4: CD0D04 call print_calc_ctl_args 18D7: FE01 cp 1 18D9: 38E5 jr c,absmt5 ; 0 args 18DB: 2807 jr z,absmt3 ; 1 arg 18DD: 18DD: 7E ld a,(hl) ; print 2 arg 18DE: A7 and a 18DF: C8 ret z 18E0: CDBC04 call print_char 18E3: 23 inc hl 18E4: 18E4: 7E absmt3 ld a,(hl) ; print 1 arg 18E5: A7 and a 18E6: C8 ret z 18E7: CDBC04 call print_char 18EA: 23 inc hl 18EB: 18D3 jr absmt5 18ED: 18ED: 18ED: 18ED: ; --------------------------------------------------------- 18ED: ; UP: print some text (hl)++ 18ED: ; in: hl -> text, delimited with 0-byte 18ED: ; de = top/left corner (e=textpixels) 18ED: ; bc = rows/cols (c=textpixels) 18ED: ; out: hl -> 0 or hl-> remaining text to print in next line 18ED: ; mod: af, bc, de, hl 18ED: 18ED: up_print_some_text 18ED: 42 ld b,d ; b = top row 18EE: 51 ld d,c ; d = c = cols retten 18EF: 4B ld c,e ; c = left col 18F0: CDF104 call print_locate ; set text location 18F3: 0600 ld b,0 18F5: 4A ld c,d ; bc = cols 18F6: 18F6: CD8205 call print_find_word_wrap ; HL BC -- DE 18F9: 18F9: A7 and a 18FA: EB ex hl,de 18FB: ED52 sbc hl,de 18FD: 444D ld bc,hl ; bc = text len 18FF: EB ex hl,de 1900: CDD304 call print_text_hlbc 1903: 09 add hl,bc 1904: C9 ret 1905: 1905: 1905: 1905: 1905: 1905: ; --------------------------------------------------------- 1905: ; print first or additional button 1905: ; 1905: ; Saves pixel to heap -> IX 1905: ; The box.in is either the box for the main text including the buttons row 1905: ; or the box for the remaining buttons only. 1905: ; In either case E = left column and C = cols are ok, the top row is calculated 1905: ; from the bottom row (D.new=D.old+B.old-B.new) and rows is set to 1 (B.new=1). 1905: ; 1905: ; in: hl -> text, delimited with 0-byte 1905: ; de = top/left corner of a box 1905: ; bc = rows/cols of a box 1905: ; out: de = top/left corner of box 1905: ; bc = rows/cols of box 1905: ; mod: af,c 1905: 1905: alert_add_button: 1905: 1905: ; calc box.top if this is the first button 1905: ; (for subsequent buttons this is a nop) 1905: 7A ld a,d ; top 1906: 80 add b ; top + rows 1907: 3D dec a 1908: 57 ld d,a 1909: 1909: E5 push hl ; hl 190A: D5 push de ; de 190B: 190B: 7B ld a,e ; box.left 190C: 81 add c ; box.cols 190D: 5F ld e,a ; e = box.right 190E: CDAD05 call print_calc_print_width ; c = text.pixels; b = 0 1911: 41 ld b,c ; b = text.pixels 1912: 1912: 78 ld a,b ; text.pixels 1913: 3D dec a 1914: F607 or 7 1916: 3C inc a 1917: 67 ld h,a ; h = text.pixels, expanded to cell boundary 1918: 1918: 0F rrca 1919: 0F rrca 191A: 0F rrca 191B: 4F ld c,a ; c = button.cols (cells) 191C: 191C: 7B ld a,e ; box.right 191D: 91 sub c ; -button.cols 191E: 5F ld e,a ; e = button.left (cells) 191F: 191F: 7C ld a,h ; a = text.pixels (expanded) 1920: 90 sub b ; a = text.pixels (expanded) -text.pixels (exact) = padding 1921: 1F rra ; a = padding/2 = padding.left (pixels) 1922: 47 ld b,a ; b = padding.left (pixels) 1923: 1923: 7B ld a,e ; a = button.left (cells) 1924: 87 add a 1925: 87 add a 1926: 87 add a ; a = button.left (pixels) 1927: 80 add b ; a = button.left + padding.left = start of text 1928: CD2105 call print_setcol 192B: 7A ld a,d 192C: CD0905 call print_setrow 192F: 192F: 0601 ld b,1 ; bc = button.cols/rows 1931: 1931: CD9B18 call alert_save_pixels 1934: 1934: 7B ld a,e ; a = button.left 1935: D1 pop de ; de = box.top/left in = out 1936: 93 sub e ; button.left - box.left = remaining box.width 1937: 3D dec a ; 1 cell spacing 1938: 4F ld c,a ; c = remaining_box.cols 1939: 1939: E1 pop hl ; hl -> text 193A: C3C204 jp print_text_hl 193D: 193D: 193D: 193D: ; --------------------------------------------------- 193D: ; Remove requester / Restore screen contents 193D: ; 193D: ; restores all pixels found on the heap up to and including 193D: ; the first attributes chunk 193D: ; 193D: ; in: -- 193D: ; out: -- 193D: ; mod: af 193D: 193D: close_alert: 193D: 193D: #if 0 193D: rst save_registers 193D: 193D: ca3 call mem_hpeek_de 193D: inc de 193D: inc de 193D: inc de 193D: ld a,(de) 193D: cp $58 193D: jp nc,scr_restore_attributes 193D: call scr_restore_pixels 193D: jr ca3 193D: 193D: #else 193D: 193D: D7 rst save_registers 193E: E7 rst vip 193F: 193F: 06 ca3 db hpeek ; handle 1940: 636312 db incr, incr, peek ; first word from data 1943: 030058E3 db number, $00, $58, ge ; compare against attr addr in screen 1947: 2D07 db bra_if, ca_attr-$ 1949: 36 db opcode 194A: 3C0D dw v_restore_pixels 194C: 2AF3 db bra, ca3-$ 194E: 194E: 69 ca_attr db to_real 194F: C37B0D jp scr_restore_attributes 1952: #endif 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: 1952: #include "alert.ass" 1952: 1952: ; -------------------------------------------------------- 1952: ; Keyboard-Routinen 1952: ; -------------------------------------------------------- 1952: 1952: ; -------------------------------------------------------- 1952: ; Tastatur-Tabellen 1952: ; -------------------------------------------------------- 1952: 1952: keycode_illegal equ 0 ; illegal codes 1952: keycode_cshift equ keycode_illegal ; single shift key 1952: keycode_sshift equ keycode_illegal ; single shift key 1952: 1952: keycode_edit equ 1 1952: keycode_capslock equ 2 1952: keycode_video equ 3 1952: keycode_rvideo equ 4 1952: keycode_left equ 5 1952: keycode_down equ 6 1952: keycode_up equ 7 1952: keycode_right equ 8 1952: keycode_graphics equ 9 1952: keycode_delete equ 10 1952: 1952: keycode_cshift_space equ 11 ; caps shift + space = Break 1952: keycode_cshift_sshift equ 12 ; caps shift + symbol shift = Extended Mode 1952: 1952: keycode_return equ 13 1952: poundsterling equ 96 1952: 1952: 1952: ; Unshifted Keys: 1952: 00 defb 0 ; => Übersetzung 0 -> 0 1953: 00 keys: defb keycode_cshift 1954: 7A786376 1958: 61736466 195C: 67 defm "zxcv", "asdfg" 195D: 71776572 1961: 74313233 1965: 3435 defm "qwert", "12345" 1967: 30393837 196B: 36706F69 196F: 7579 defm "09876", "poiuy" 1971: 0D defb keycode_return 1972: 6C6B6A68 1976: 20 defm "lkjh", " " 1977: 00 defb keycode_sshift 1978: 6D6E62 defm "mnb" 197B: 197B: ; Key + Symbol Shift: 197B: 00 skeys: defb keycode_cshift 197C: 3A603F2F defb ':', poundsterling, '?', '/' 1980: 7E7C5C7B 1984: 7D717765 1988: 3C3E2140 198C: 232425 defm "~|\{}", "qwe<>", "!@#$%" 198F: 5F292827 1993: 26 defm "_)('&" 1994: 223B495D 1998: 5B defm '";I][' 1999: 0D defb keycode_return 199A: 3D2B2D5E 199E: 20 defm "=+-^", " " 199F: 00 defb keycode_sshift 19A0: 2E2C2A defm ".,*" 19A3: 19A3: ; Key + Caps Shift: 19A3: 00 ckeys: defb keycode_cshift 19A4: 5A584356 19A8: 41534446 19AC: 47515745 19B0: 5254 defm "ZXCV", "ASDFG", "QWERT" 19B2: 01020304 19B6: 05 defb keycode_edit, keycode_capslock, keycode_video, keycode_rvideo, keycode_left 19B7: 0A090807 19BB: 06 defb keycode_delete, keycode_graphics, keycode_right, keycode_up, keycode_down 19BC: 504F4955 19C0: 59 defm "POIUY" 19C1: 0D defb keycode_return 19C2: 4C4B4A48 defm "LKJH" 19C6: 0B defb keycode_cshift_space 19C7: 0C defb keycode_cshift_sshift 19C8: 4D4E42 defm "MNB" 19CB: 19CB: keys_end: 19CB: 19CB: 19CB: 19CB: ; -------------------------------------------------------- 19CB: ; Initialisierung: No Action 19CB: ; Ann.: Data-Bereich wird bei Systemstart genullt. 19CB: ; "irpt_scan_keyboard" muss in der Interrupt-Routine aufgerufen werden. 19CB: ; 19CB: ; in: -- 19CB: ; out: -- 19CB: ; mod: -- 19CB: 19CB: init_keyboard: 19CB: C9 ret 19CC: 19CC: 19CC: 19CC: ; -------------------------------------------------------- 19CC: ; Flush Input und warte auf eine neue Taste 19CC: ; 19CC: ; Der Tastaturpuffer wird geleert und es wird gewartet, 19CC: ; bis eine evtl. noch gedrückte Taste gelöst wird. 19CC: ; Erst danach wird auf eine neue Taste gewartet. 19CC: ; 19CC: ; Diese Routine sollte benutzt werden, wenn das Programm 19CC: ; überraschende Eingaben erwartet, z.B. nach "Scroll?" 19CC: ; 19CC: ; in: -- 19CC: ; out: -- 19CC: ; mod: af 19CC: 19CC: wait_newkey: 19CC: CDD619 call flush_inkey 19CF: ;jr wait_inkey 19CF: 19CF: 19CF: 19CF: ; -------------------------------------------------------- 19CF: ; Lese Zeichen aus Tastaturpuffer: 19CF: ; Wartet bis Zeichen verfügbar. 19CF: ; Ansonsten wie "get_inkey". 19CF: ; 19CF: ; in: -- 19CF: ; out: a: Zeichen aus Tastaturpuffer 19CF: ; mod: af 19CF: 19CF: wait_inkey: 19CF: CDE619 call get_inkey 19D2: C0 ret nz ; -> ret nz & a!=0 19D3: 76 halt 19D4: 18F9 jr wait_inkey 19D6: 19D6: 19D6: 19D6: ; -------------------------------------------------------- 19D6: ; Lösche Tastaturpuffer und warte, bis keine Taste mehr gedrückt ist. 19D6: ; 19D6: ; in: -- 19D6: ; out: -- 19D6: ; mod: af 19D6: 19D6: flush_inkey: 19D6: 3A355B ld a,(key_oldkey) ; zuerst key_oldkey lesen 19D9: D9 exx 19DA: 210000 ld hl,0 19DD: 22335B ld (key_inkey),hl ; dann key_inkey löschen 19E0: D9 exx 19E1: A7 and a 19E2: C8 ret z 19E3: 76 halt 19E4: 18F0 jr flush_inkey 19E6: 19E6: 19E6: 19E6: ; -------------------------------------------------------- 19E6: ; Lese Zeichen aus Tastaturpuffer: 19E6: ; 19E6: ; Es wird entweder 0 (nokey), ein druckbares Zeichen oder ein Controlcode zurückgeliefert. 19E6: ; Controlcodes sind wie oben definiert. 19E6: ; Druckbare Zeichen außer "poundsterling" sind alle 7-Bit-Ascii. 19E6: ; 19E6: ; in: -- 19E6: ; out: a: Zeichen aus Tastaturpuffer oder 0 (nokey) 19E6: ; f: z-Flag zeigt an, ob a=0 (nokey) oder a=Zeichencode 19E6: ; mod: af 19E6: 19E6: get_inkey: 19E6: E5 push hl 19E7: 19E7: ; hole Tastencode 19E7: 2A335B ld hl,(key_inkey) 19EA: 7D ld a,l 19EB: 6C ld l,h 19EC: 2600 ld h,0 19EE: 22335B ld (key_inkey),hl 19F1: 19F1: ; Konvertiere Tastencode in Zeichencode: 19F1: 215219 ld hl,keys -1 19F4: FE41 cp $41 ; unshifted? 19F6: 3808 jr c,kfs_x ; ja 19F8: D618 sub 24 ; sshift_mask - 40 19FA: FE69 cp $81-24 ; mit symbol shift? 19FC: 3802 jr c,kfs_x ; ja 19FE: D618 sub 24 ; sonst mit caps shift 1A00: 1A00: 85 kfs_x add l ; hl += a 1A01: 6F ld l,a 1A02: 3001 jr nc,$+3 1A04: 24 inc h 1A05: 1A05: 7E ld a,(hl) ; hole Zeichencode 1A06: 1A06: E1 pop hl 1A07: A7 and a ; -> ret z / ret nz 1A08: C9 ret 1A09: 1A09: 1A09: ; -------------------------------------------------------- 1A09: ; Bis zu drei gleichzeitig gedrückte Tasten werden sinnvoll behandelt: 1A09: ; 1A09: ; - keine Taste Trivial 1A09: ; 1A09: ; - eine Shifttaste wird nicht gepostet 1A09: ; - eine normale Taste wird gepostet 1A09: ; 1A09: ; - beide Shifttasten => normale Taste "Symbolshift" + Caps-Shiftflag 1A09: ; - eine normale Taste + eine Shifttaste => normale Taste + entsprechendes Shiftflag 1A09: ; - zwei normale Tasten Ann.: Überlappung von Tastenaschlägen bei schnellem Tippen: 1A09: ; Die die bisher gedrückte Taste wird als gelöst betrachtet 1A09: ; und die neue gepostet 1A09: ; - zwei normale Tasten + eine Shifttaste dito, nur mit zus. Shiftflag 1A09: ; - eine normale Taste + beide Shifttasten dito, "Symbolshift" wird als normale Taste behandelt 1A09: 1A09: 1A09: 1A09: ; Puffer für bis zu 2 Zeichen zur Übergabe der Tastenscancodes an die Applikation: 1A09: 1A09: key_inkey data 2 ; nokey (0) oder Scancode [1..40] + sshift ($40) + cshift ($80) 1A09: 1A09: 1A09: 1A09: ; Eine Zelle für die beim letzten Scannen erkannte Taste: 1A09: ; 1A09: ; Shifttasten werden als Flags im Tastencode gespeichert und für die gesamte Dauer der Taste 1A09: ; (Autorepeats) so angewandt, wie sie zum Zeitpunkt des Drückens der Taste aktiv waren. 1A09: 1A09: key_oldkey data 1 ; 0 = no Key; sonst: Keycode [1..40] + Shift-Flags 1A09: 1A09: nokey equ 0 ; Zelle leer 1A09: cshift_scancode equ 1 ; bei range [1..40] 1A09: sshift_scancode equ 37 ; bei range [1..40] 1A09: 1A09: sshift_mask equ $40 ; Symbol Shift war zum Drückzeitpunkt aktiv 1A09: cshift_mask equ $80 ; Caps Shift war zum Drückzeitpunkt aktiv 1A09: sshift_bit equ 6 1A09: cshift_bit equ 7 1A09: 1A09: 1A09: ; Timer für Entprellschutz und Autorepeat: 1A09: ; 1A09: ; startdelay + guardtime .. startdelay => Entprellschutz 1A09: ; startdelay .. 0 => Wartezeit bis zum ersten Autorepeat 1A09: ; repeatdelay .. 0 => Wartezeit bis zu weiteren Autorepeats 1A09: 1A09: key_timer data 1 ; Countdown für Guardtime und bis Autorepeat 1A09: 1A09: key_guardtime equ 2 ; 2/50 sec. Entprellschutzzeit 1A09: key_startdelay equ 10 ; 10/50 sec. Delay bis zum ersten Autorepeat 1A09: key_repeatdelay equ 4 ; 4/50 sec. Delay bis zu weiteren Repeats 1A09: 1A09: 1A09: 1A09: 1A09: 1A09: 1A09: 1A09: ; ------------------------------------------------ 1A09: ; Scan Keyboard (Interruptroutine) 1A09: ; in: -- 1A09: ; out: -- 1A09: ; mod: af, bc, de, hl 1A09: 1A09: 1A09: irpt_scan_keyboard: 1A09: 1A09: ; Prüfe, ob die Guardtime für die zuletzt erkannte Taste noch läuft: 1A09: ; In dieser Zeit, kann die (existierende!) Taste nicht gelöscht werden 1A09: ; und logischerweise auch noch keine Autorepeats erzeugen. 1A09: ; Das gilt für eine normale Taste und max. ein Shiftbit im Tastencode. 1A09: ; Nur wenn key_oldkey nur aus einem Shiftbit ohne eine normale Taste besteht, 1A09: ; kann das andere Shiftbit (-> Extended Mode) oder eine normale Taste dazu kommen, 1A09: ; wobei dann ein Tastenevent nach key_inkey geschrieben werden muss. 1A09: 1A09: 21365B ld hl,key_timer ; hl -> key_timer 1A0C: 3E0A ld a,key_startdelay 1A0E: BE cp (hl) 1A0F: 300C jr nc,isk01 ; timer ≤ startdelay => guardtime abgelaufen 1A11: 1A11: ; Guardtime ist noch aktiv: 1A11: ; => prüfe, ob sie nur für ein Shiftbit gilt: 1A11: 3A355B ld a,(key_oldkey) ; zugehörige Taste 1A14: 57 ld d,a ; d = Shiftflag (Ann.: alte Taste = einzelne Shifttaste) 1A15: E63F and $3f ; w/o Shiftflags 1A17: 2806 jr z,isk001 ; nokey -> Guardtime nur für einzelne Shifttaste 1A19: 1A19: ; Guardtime noch aktiv oder key_inkey nicht frei. 1A19: ; => Tastatur nicht scannen, weil Änderungen nicht gespeichert werden können. 1A19: ; Timer runterzählen aber nicht bis 0. (Autorepeat verzögern) 1A19: 1A19: isk0 ;ld hl,key_timer 1A19: 35 dec (hl) ; key_timer-- 1A1A: C0 ret nz 1A1B: 34 inc (hl) ; delay autorepeat 1A1C: C9 ret 1A1D: 1A1D: ; Guardtime abgelaufen ((isk01)) oder 1A1D: ; Guardtime gilt nur für ein einzelnes Shiftbit ((isk001)) 1A1D: ; => Prüfe, ob key_inkey frei ist: 1A1D: ; Solange der Tastenpuffer nicht frei ist, ist das Scannen der Tastatur nutzlos, 1A1D: ; da keine neue Taste oder Autorepeat gespeichert werden. => Exit. 1A1D: 1A1D: 1600 isk01 ld d,0 ; d = neue Tasten = nokey; isk001: d = Shiftbit 1A1F: 3A345B isk001 ld a,(key_inkey+1) 1A22: A7 and a 1A23: 20F4 jr nz,isk0 ; Tastenpuffer ist belegt! => Exit 1A25: 1A25: 1A25: ; ---------------------------------- 1A25: ; Guardtime für alte Taste ist nicht mehr aktiv oder gilt nur für ein enzelnes Shiftbit: 1A25: ; => Eine neue Taste kann auch gespeichert werden. 1A25: ; => Scan Keyboard. 1A25: 1A25: ;ld d,d ; d = neue Taste + Shiftflags 1A25: 1E00 ld e,0 ; e = keyboard row number [0..7] 1A27: 01FEFE ld bc,$fefe ; bc = IO address incl. key row sub address in B 1A2A: 1805 jr isk3 1A2C: 1A2C: ; Schleife über alle Tastenzeilen: 1A2C: 1C isk4 inc e ; e = row number ++ 1A2D: CB00 rlc b ; b = next IO key row sub address 1A2F: 3047 jr nc,isk11 ; fertig 1A31: 1A31: ED78 isk3 in a,(c) ; a = new key bits 1A33: 2F cpl ; pressed keys := '1' 1A34: E61F and $1f ; mask 5 valid keys 1A36: 28F4 jr z,isk4 ; no pressed key(s) found 1A38: 1A38: ; Tastenzeile enthält gedrückte Tasten: 1A38: ; f = nc, a = key code, bc=IO address, d = current keys, e = row number, hl = -- 1A38: 67 ld h,a ; h = key bits 1A39: 7B ld a,e ; row number 1A3A: 87 add a 1A3B: 87 add a 1A3C: 83 add e ; *5 1A3D: 6F ld l,a ; l = current key code 1A3E: 1A3E: ; Schleife über Tasten (Bits): 1A3E: ; a = --, f = nc, bc = io address, d = current keys, e = row number, h = key bits, l = current key code 1A3E: 2C isk5 inc l ; next key code 1A3F: ;and a ; clear c-flag 1A3F: CB1C rr h ; key bits 1A41: 30FB jr nc,isk5 ; key not pressed -> try next bit 1A43: 1A43: ; Gedrückte Taste gefunden: 1A43: ; a = --, bc = io address, d = current keys, e = row number, h = key bits, l = new key code 1A43: ; auf Shifttaste prüfen und ggf. in Shiftflag umwandeln: 1A43: 7D ld a,l ; new key code 1A44: FE01 cp cshift_scancode ; caps shift key? 1A46: 2004 jr nz,isk7 ; no 1A48: CBFA set cshift_bit,d ; d += cshift 1A4A: 1806 jr isk61 1A4C: FE25 isk7 cp sshift_scancode ; symbol shift key? 1A4E: 200B jr nz,isk8 ; no -> normale Taste in l 1A50: CBF2 set sshift_bit,d ; d += sshift 1A52: 1A52: ; Neue Taste war eine Shifttaste. 1A52: ; Auf beide Shifttasten prüfen und ggf. durch legalen Code ersetzen: 1A52: 7A isk61 ld a,d 1A53: FEC0 cp $c0 ; jetzt beide Shifttasten? 1A55: 381B jr c,isk6 ; no -> ok -> loop 1A57: 1A57: ; Jetzt sind beide Shifttasten gedrückt. 1A57: ; -> Current key in d durch legalen Code ersetzen 1A57: ; auf 2 Shifttasten + normale Taste testen 1A57: CBB2 res sshift_bit,d ; d = alte normale Taste (if any) + Caps Shift Bit 1A59: 2E25 ld l,sshift_scancode ; l = neue normale Taste "Symbol Shift" 1A5B: ;jr isk8 1A5B: 1A5B: 1A5B: ; ---------------------------------- 1A5B: ; normale Taste l gefunden: 1A5B: 7A isk8 ld a,d ; a = new key 1A5C: E63F and $3f ; w/o shift flag 1A5E: 280F jr z,isk10 ; es gibt noch keine andere 'normale Taste' 1A60: 1A60: ; 2 normale Tasten (d und l) gefunden: 1A60: ; Ann.: Durch schnelles Tippen können kurzzeitig zwei Tasten gedrückt sein. 1A60: ; -> (1) Taste d ist alt und l ist neu => d vergessen, l triggern 1A60: ; (2) Taste l ist alt und d ist neu => l vergessen, d triggern 1A60: ; (3) beide Tasten sind neu => Ghostkey (oder abusive usage) 1A60: ; 1A60: ; (1), (2) Die Guardtime verhindert, dass diese Stellung beim nächsten Interrupt sofort 1A60: ; erneut umschaltet, und so mit 50 Hz Tastenevents für diese Tasten erzeugt würden. 1A60: ; Die Guardtime für diese neue Taste sollte ausreichen, dass die alte Taste tatsächlich 1A60: ; hochgeht und nach Ablauf der Guardtime tatsächlich nicht mehr unten ist. 1A60: ; Wenn aber jemand zwei Tasten gedrückt hält, kommt es jeweils nach Ablauf der Guardtime 1A60: ; zu einem alternierenden Triggern dieser beiden Tasten. 1A60: ; 1A60: ; (3) Schnelles Tippen bei konstant gedrückter Shifttaste kann zu 3 Tasten plus Ghostkey führen. 1A60: ; Wenn Tasten d und l beide neu sind ist eine davon wahrscheinlich einen Ghostkey 1A60: ; und es gibt eine alte Taste und es ist eine Shifttaste gedrückt. (sonst: abusive usage => egal) 1A60: ; Da nicht entschieden werden kann, welche der beiden neuen Tasten nur ein Ghostkey ist, 1A60: ; bleibt nichts weiter übrig, als zu warten, dass die alte Taste hochgeht und der 1A60: ; Ghostkey somit verschwindet. => keine neue Taste und kein Autorepeat posten, Warten => Exit 1A60: 1A60: 3A355B ld a,(key_oldkey) ; alte Taste 1A63: E63F and $3f ; ohne Shiftbits 1A65: BD cp l 1A66: 280A jr z,isk6 ; Taste l ist die alte und geht hoch -> d bleibt d -> loop 1A68: 1A68: AA xor d 1A69: E63F and $3f 1A6B: C0 ret nz ; Taste d und l sind neu => Ghostkey! 1A6C: 1A6C: ; Taste d ist die alte und geht hoch 1A6C: 7A ld a,d ; a = ältere Taste incl. Shiftbits 1A6D: E63F and $3f ; a = ältere Taste 1A6F: 1A6F: ; 1. normale Taste gefunden: 1A6F: AA isk10 xor d ; a = Shiftbits 1A70: B5 or l ; a = neue Taste incl. Shiftbits 1A71: 57 ld d,a ; d = neue Taste incl. Shiftbits: fertig 1A72: ;jr isk6 ; und weiter nach Tasten suchen 1A72: 1A72: ; Taste abgehandelt, nach weiteren Tasten suchen: 1A72: 7C isk6 ld a,h ; remaining key bits 1A73: A7 and a ; Test for z and clear cy 1A74: 28B6 jr z,isk4 ; keine Tasten mehr drin => nächste Zeile 1A76: 18C6 jr isk5 ; weitere Tasten drin => weiter suchen 1A78: 1A78: 1A78: 1A78: 1A78: ; ---------------------------------- 1A78: ; Keyboardmatrix ist gescannt. 1A78: ; d = new key = Nokey|Tastencode + Noshift|SShift|CShift 1A78: ; old key = Nokey|Tastencode + Noshift|SShift|CShift 1A78: 1A78: 21355B isk11 ld hl,key_oldkey ; hl -> key_oldkey 1A7B: 7A ld a,d ; new key 1A7C: E63F and $3f 1A7E: 200A jr nz,isk111 ; es ist eine normale Taste gedrückt 1A80: 1A80: ; Es ist keine Taste oder nur eine Shifttaste gedrückt: 1A80: ; => kein neues Tastenevent oder Autorepeat 1A80: ; 1A80: ; Guardtime noch gültig? 1A80: ; (old key == new key == Shifttaste) 1A80: ; timer-- 1A80: ; Guardtime abgelaufen? 1A80: ; new key == nokey? 1A80: ; old key := new key = d = nokey 1A80: ; timer egal 1A80: ; new key == shift key? 1A80: ; (es könnte jetzt auch die andere Shifttaste sein.) 1A80: ; old key == nokey? 1A80: ; old key := new key = d = shiftkey 1A80: ; timer := startdelay + guardtime 1A80: ; old key != nokey? 1A80: ; old key := new key = d = shiftkey 1A80: ; timer-- aber nicht auf 0 1A80: ; 1A80: AE xor a,(hl) ; a = old key & set flags 1A81: 72 ld (hl),d ; old key := new key 1A82: 23 inc hl ; hl -> key_timer 1A83: 2094 jr nz,isk0 ; old key != nokey => old key == shiftkey => new key egal => timer-- & exit 1A85: AA xor d ; a = new key & set flags 1A86: C8 ret z ; old key == nokey && new key == nokey => timer egal & exit 1A87: 1A87: ; old key == nokey && new key != nokey 1A87: ; => shiftkey goes down: 1A87: 360C ld (hl),key_startdelay + key_guardtime 1A89: C9 ret 1A8A: 1A8A: 1A8A: ; Es ist eine normale Taste und evtl. eine Shifttaste in d gedrückt: 1A8A: ; 1A8A: ; neue Taste ohne Shiftbits != alte Taste ohne Shiftbits? 1A8A: ; ignore whether old key is still down 1A8A: ; neue Taste posten 1A8A: ; old key := new key 1A8A: ; timer := guardtime 1A8A: ; neue Taste ohne Shiftbits == alte Taste ohne Shiftbits? 1A8A: ; old key untouched (ignore change of shift keys!) 1A8A: ; key_inkey[0] leer? 1A8A: ; timer-- 1A8A: ; Timer abgelaufen? 1A8A: ; Autorepeat posten 1A8A: ; timer := repeatdelay 1A8A: ; key_inkey[0] nicht leer? 1A8A: ; timer-- aber nicht bis 0 1A8A: ; 1A8A: 7E isk111 ld a,(hl) ; old key 1A8B: AA xor d ; new key 1A8C: E63F and $3f ; w/o shiftbits 1A8E: 2011 jr nz,isk13 ; Haupttaste änderte sich 1A90: 1A90: ; Haupttaste blieb gleich: 1A90: 23 inc hl ; hl-> key_timer 1A91: 35 dec (hl) ; timer-- 1A92: C0 ret nz ; repeatdelay noch nicht abgelaufen => fertig! 1A93: ; Autorepeat, außer wenn inkey buffer nicht ganz leer: 1A93: 3A335B ld a,(key_inkey) ; key_inkey[0] 1A96: A7 and a 1A97: 2802 jr z,isk112 ; inkey buffer leer 1A99: 34 inc (hl) ; noch eine Taste im inkey buffer => delay autorepeat! 1A9A: C9 ret 1A9B: ; Autorepeat 1A9B: 3604 isk112 ld (hl),key_repeatdelay ; timer := repeat delay 1A9D: 2B dec hl ; hl -> key_oldkey 1A9E: 56 ld d,(hl) ; d = old key with with old shift flags 1A9F: 1804 jr isk14 ; post it & exit 1AA1: 1AA1: ; Haupttaste änderte sich => neue Haupttaste 1AA1: 72 isk13 ld (hl),d ; old key := new key incl. new shift flags 1AA2: 23 inc hl ; hl -> key_timer 1AA3: 360C ld (hl),key_startdelay + key_guardtime 1AA5: ;jr isk14 ; post it & exit 1AA5: 1AA5: ; post key in d: 1AA5: 21335B isk14 ld hl,key_inkey ; hl -> key_inkey[0] 1AA8: 7E ld a,(hl) 1AA9: A7 and a 1AAA: 2801 jr z,$+3 ; key_inkey[0] ist frei; sonst 1AAC: 23 inc hl ; hl -> key_inkey[1] 1AAD: 72 ld (hl),d ; post new key 1AAE: C9 ret 1AAF: 1AAF: 1AAF: 1AAF: 1AAF: 1AAF: 1AAF: #include "keyboard.ass" 1AAF: 1AAF: 1AAF: ; -------------------------------------------------------- 1AAF: ; IC Tester I/O 1AAF: ; -------------------------------------------------------- 1AAF: 1AAF: io_pins data 1 ; Anzahl Pins IC gesamt (-> nur gerade Werte) 1AAF: io_flags data 1 1AAF: io_flag_irpt equ 7 ; io_flags.bit(7) = enable pin display update on interrupt 1AAF: 1AAF: io_bits_table data 0 ; io pin state table: 1AAF: 1AAF: io_bits_l data 0 ; leftside pins: bit 0=top 1AAF: io_bits_A8 data 4 ; pin 1..8 top 1AAF: io_bits_A9 data 4 ; pin 9..16 middle 1AAF: io_bits_A10 data 4 ; pin 17..24 bottom 1AAF: 1AAF: io_bits_r data 0 ; rightside pins: bit 7=top 1AAF: io_bits_A11 data 4 ; pin 25..32 bottom 1AAF: io_bits_A12 data 4 ; pin 33..40 middle 1AAF: io_bits_A13 data 4 ; pin 41..48 top 1AAF: 1AAF: io_offset_out equ 0 ; offset +0: out value 1AAF: io_offset_in equ 2 ; offset +2: input value 1AAF: io_offset_new equ 0 ; offset +0: new (to be displayed) value 1AAF: io_offset_old equ 1 ; offset +1: old (displayed) value 1AAF: 1AAF: io_bits_data_size equ 4 1AAF: io_bits_table_size equ 4*6 1AAF: 1AAF: ; where to display graphics: 1AAF: ic_middle equ 24 ; 23|24 1AAF: 1AAF: ic_col_lout equ ic_middle-8 ; linke Seite: obits 1 char 1AAF: ic_col_ltype equ ic_middle-7 ; pin type: 2 char 1AAF: ic_col_lin equ ic_middle-5 ; ibits 1 char 1AAF: ic_col_lname equ ic_middle-4 ; pin name: 4 char 1AAF: 1AAF: ic_col_rname equ ic_middle+0 ;Rechte Seite: pin name: 4 char 1AAF: ic_col_rin equ ic_middle+4 ; ibits 1 char 1AAF: ic_col_rtype equ ic_middle+5 ; pin type: 2 char 1AAF: ic_col_rout equ ic_middle+7 ; obits 1 char 1AAF: 1AAF: ic_pin_name_sz equ 6 ; max. 5 char + terminating $00 1AAF: ic_pin_name data 48 * ic_pin_name_sz 1AAF: ic_pin_type data 48 1AAF: 1AAF: ic_pin_type_unknown equ 0 1AAF: ic_pin_type_gnd equ 1 1AAF: ic_pin_type_vcc equ 2 1AAF: ic_pin_type_input equ 3 1AAF: ic_pin_type_output equ 4 1AAF: ic_pin_type_io equ 5 1AAF: ic_pin_type_oK equ 6 1AAF: ic_pin_type_3state equ 7 1AAF: ic_pin_type_nc equ 8 1AAF: 1AAF: 1AAF: 1AAF: 1AAF: 1AAF: ; -------------------------------------------------------- 1AAF: ; in: a = pin 1AAF: ; out: hl -> pin type 1AAF: ; a = pin type 1AAF: ; mod: af, hl 1AAF: 1AAF: get_pin_type: 1AAF: 21715C ld hl,ic_pin_type 1AB2: 85 add l 1AB3: 6F ld l,a 1AB4: #if ic_pin_type/256 != (ic_pin_type+47)/256 1AB4: ld a,(hl) 1AB4: ret nc 1AB4: inc h 1AB4: #endif 1AB4: 7E ld a,(hl) 1AB5: C9 ret 1AB6: 1AB6: 1AB6: 1AB6: ; -------------------------------------------------------- 1AB6: ; in: a = pin 1AB6: ; b = type 1AB6: ; out: hl -> pin type 1AB6: ; mod: af, hl 1AB6: 1AB6: set_pin_type: 1AB6: 21715C ld hl,ic_pin_type 1AB9: 85 add l 1ABA: 6F ld l,a 1ABB: #if ic_pin_type/256 != (ic_pin_type+47)/256 1ABB: jr nc,$+3 1ABB: inc h 1ABB: #endif 1ABB: 70 ld (hl),b 1ABC: C9 ret 1ABD: 1ABD: 1ABD: 1ABD: ; -------------------------------------------------------- 1ABD: ; Set pin type for current pin 1ABD: ; and update display for this pin 1ABD: ; 1ABD: ; in: -- 1ABD: ; out: -- 1ABD: ; mod: 1ABD: 1ABD: ic_set_pin_type_for_current_pin: 1ABD: 5F ld e,a ; typ retten 1ABE: CD951B call calc_pin_from_hilight ; a = pin 1AC1: 43 ld b,e ; b = typ 1AC2: 5F ld e,a ; pin retten 1AC3: CDB61A call set_pin_type 1AC6: 7B ld a,e 1AC7: 180E jr ic_draw_pin_type 1AC9: 1AC9: 1AC9: 1AC9: ; -------------------------------------------------------- 1AC9: ; Draw pin type for all pins 1AC9: 1AC9: ic_draw_all_pin_types: 1AC9: 3E2F ld a,47 1ACB: F5 icdap1 push af 1ACC: CDD71A call ic_draw_pin_type 1ACF: F1 pop af 1AD0: 3D dec a 1AD1: F8 ret m 1AD2: 18F7 jr icdap1 1AD4: 1AD4: 1AD4: 1AD4: ; -------------------------------------------------------- 1AD4: ; in: -- 1AD4: 1AD4: ic_draw_pin_type_for_current_pin: 1AD4: CD951B call calc_pin_from_hilight ; a = pin 1AD7: ;jr ic_draw_pin_type 1AD7: 1AD7: 1AD7: 1AD7: ; -------------------------------------------------------- 1AD7: ; in: a = pin [0..47] 1AD7: 1AD7: ic_draw_pin_type: 1AD7: F5 push af ; sp: pin no. 1AD8: 112D1B ld de,ic_pin_type_text_l 1ADB: 1ADB: 0E11 ld c,ic_col_ltype ; c=col 1ADD: FE18 cp 24 1ADF: 3808 jr c,icdp1 ; pin _is_ left side => calues ok 1AE1: 1AE1: ; pin is on right side => adjust values 1AE1: 11121B ld de,ic_pin_type_text_r 1AE4: 2F cpl ; a = -1 -pin_no 1AE5: C630 add 48 ; a = 47 -pin_no 1AE7: 0E1D ld c,ic_col_rtype ; c=col 1AE9: 1AE9: 47 icdp1 ld b,a ; b=row 1AEA: 1AEA: CD480E call calc_pixel_hl_for_row_b_col_c 1AED: 1AED: 220C5B ld (print_hl),hl ; locate text vdu 1AF0: 3E80 ld a,$80 1AF2: 320E5B ld (print_c),a 1AF5: 3E68 ld a,black+cyan_paper+bright ; set attr 1AF7: 320F5B ld (print_attr),a 1AFA: 1AFA: 010201 ld bc,256*1 + 2 ; rows=2, cols=1 1AFD: CD410C call clear_pixels 1B00: 1B00: F1 pop af ; pin no. 1B01: CDAF1A call get_pin_type ; -> a = type 1B04: 3D dec a 1B05: F8 ret m ; typ 0 = unknown => no text 1B06: 1B06: ; de still points to either ic_pin_type_text_l or ic_pin_type_text_r 1B06: ; access and print message for pin type A: 1B06: EB ex hl,de ; hl -> offset-to-message table 1B07: 85 add l 1B08: 6F ld l,a ; hl -> offset-to-message byte 1B09: 86 add (hl) 1B0A: 6F ld l,a 1B0B: D2C204 jp nc,print_text_hl 1B0E: 24 inc h 1B0F: C3C204 jp print_text_hl 1B12: 1B12: 1B12: #if $/256 != ($+7)/256 1B12: defs 256-$%256 1B12: #endif 1B12: ic_pin_type_text_r 1B12: 08 defb icptr1-$ 1B13: 09 defb icptr2-$ 1B14: 0A defb icptr3-$ 1B15: 0B defb icptr4-$ 1B16: 0C defb icptr5-$ 1B17: 0D defb icptr6-$ 1B18: 0F defb icptr7-$ 1B19: 11 defb icptr8-$ 1B1A: 1B1A: 9600 icptr1 defb charcode_gnd,0 ; gnd 1B1C: 9700 icptr2 defb charcode_vcc,0 ; vcc 1B1E: 9B00 icptr3 defb charcode_i_right,0 ; input 1B20: 9A00 icptr4 defb charcode_o_right,0 ; output 1B22: 9500 icptr5 defb charcode_io,0 ; i/o 1B24: 999A00 icptr6 defb charcode_oK,charcode_o_right,0 ; output oK 1B27: 989A00 icptr7 defb charcode_3state,charcode_o_right,0 ; output 3state 1B2A: 6E6300 icptr8 defb "nc",0 ; n.c. 1B2D: 1B2D: 1B2D: #if $/256 != ($+7)/256 1B2D: defs 256-$%256 1B2D: #endif 1B2D: ic_pin_type_text_l 1B2D: 08 defb icptl1-$ 1B2E: 0B defb icptl2-$ 1B2F: 0E defb icptl3-$ 1B30: 11 defb icptl4-$ 1B31: 14 defb icptl5-$ 1B32: 17 defb icptl6-$ 1B33: 1B defb icptl7-$ 1B34: 1F defb icptl8-$ 1B35: 1B35: 048F9600 icptl1 defb ctl_setcol,128+3*8-(c23-c22+2),charcode_gnd,0 ; gnd 1B39: 048F9700 icptl2 defb ctl_setcol,128+3*8-(c24-c23+2),charcode_vcc,0 ; vcc 1B3D: 04909A00 icptl3 defb ctl_setcol,128+3*8-(c27-c26+2),charcode_i_left,0 ; input 1B41: 04909B00 icptl4 defb ctl_setcol,128+3*8-(c28-c27+2),charcode_o_left,0 ; output 1B45: 048E9500 icptl5 defb ctl_setcol,128+3*8-(c22-c21+2),charcode_io,0 ; i/o 1B49: 04899B99 1B4D: 00 icptl6 defb ctl_setcol,128+3*8-(c28-c27+c26-c25+4),charcode_o_left,charcode_oK,0 ; output oK 1B4E: 04899B98 1B52: 00 icptl7 defb ctl_setcol,128+3*8-(c28-c27+c25-c24+4),charcode_o_left,charcode_3state,0 ; output 3state 1B53: 048B6E63 1B57: 00 icptl8 defb ctl_setcol,128+3*8-(c111-c110+c100-c99+4),"nc",0 ; n.c. 1B58: 1B58: 1B58: 1B58: ; -------------------------------------------------------- 1B58: ; calc. Address and bitmask for pin 1B58: ; 1B58: ; in: HL -> array[6] 1B58: ; A = pin no. [0..47] 1B58: ; out: HL -> array[n/8] 1B58: ; A = bitmask 1B58: ; mod: af, de, hl 1B58: 1B58: calc_hl_mask_a_for_pin: 1B58: FE18 cp 24 ; which side? 1B5A: 3002 jr nc,$+4 ; right-side pins are numbered %76543210 => matches bmasks[] 1B5C: EE07 xor 7 ; left-side pins are numbered %01234567 => reverted bit order 1B5E: 1B5E: 5F ld e,a ; a retten 1B5F: 0F rrca 1B60: 0F rrca 1B61: 0F rrca 1B62: E607 and 7 1B64: 85 add l 1B65: 3001 jr nc,$+3 1B67: 24 inc h 1B68: 7B ld a,e ; a = pin no. 1B69: 1B69: ; calc_bmask: 1B69: 119F1F ld de,bmasks 1B6C: E607 and 7 1B6E: 83 add e 1B6F: 5F ld e,a 1B70: 1A ld a,(de) 1B71: C9 ret 1B72: 1B72: 1B72: 1B72: 1B72: 1B72: 1B72: 1B72: 1B72: ; -------------------------------------------------------- 1B72: ; in: A = pin no. [0..47] 1B72: ; out: HL -> attr 1B72: ; mod: AF, BC, HL 1B72: 1B72: calc_attr_hl_for_name: 1B72: 0E14 ld c,ic_col_lname 1B74: FE18 cp 24 1B76: 3819 jr c,ca1 1B78: 0E18 ld c,ic_col_rname 1B7A: 1812 jr ca2 1B7C: 1B7C: calc_attr_hl_for_type: 1B7C: 0E11 ld c,ic_col_ltype 1B7E: FE18 cp 24 1B80: 380F jr c,ca1 1B82: 0E1D ld c,ic_col_rtype 1B84: 1808 jr ca2 1B86: 1B86: calc_attr_hl_for_obit: 1B86: 0E10 ld c,ic_col_lout ; col 1B88: FE18 cp 24 1B8A: 3805 jr c,ca1 ; linke Seite 1B8C: 1B8C: 0E1F ld c,ic_col_rout ; col 1B8E: 2F ca2 cpl ; rechte Seite 1B8F: C630 add 48 1B91: 47 ca1 ld b,a ; row 1B92: C3390E jp calc_attr_hl_for_row_b_col_c 1B95: 1B95: 1B95: 1B95: ; -------------------------------------------------------- 1B95: ; Berechne aus row B und col C die zugehörige Pinnummer 1B95: ; 1B95: ; in: B = row 1B95: ; C = col 1B95: ; out: A = pin [0..47] 1B95: 1B95: calc_pin_from_hilight: 1B95: ED4BA15C ld bc,(ic_hilight_row_col) ; b=row, c=col 1B99: 1B99: calc_pin_from_rowcol: 1B99: 79 ld a,c ; col 1B9A: FE18 cp ic_middle ; links der Mitte? 1B9C: 78 ld a,b ; dann pin = row 1B9D: D8 ret c ; ja: linke Seite 1B9E: 3E2F ld a,47 1BA0: 90 sub b ; sonst rechte Seite 1BA1: C9 ret ; pin = 47 - row 1BA2: 1BA2: 1BA2: 1BA2: test_col_c_is_obit: 1BA2: 79 ld a,c 1BA3: FE10 cp ic_col_lout ; z -> ja 1BA5: C8 ret z 1BA6: FE1F cp ic_col_rout ; z -> ja 1BA8: C9 ret 1BA9: 1BA9: test_col_c_is_name: 1BA9: 79 ld a,c 1BAA: FE14 cp ic_col_lname ; z -> ja 1BAC: C8 ret z 1BAD: FE18 cp ic_col_rname ; z -> ja 1BAF: C9 ret 1BB0: 1BB0: test_col_c_is_type: 1BB0: 79 ld a,c 1BB1: FE11 cp ic_col_ltype ; z -> ja 1BB3: C8 ret z 1BB4: FE1D cp ic_col_rtype ; z -> ja 1BB6: C9 ret 1BB7: 1BB7: 1BB7: ; -------------------------------------------------------- 1BB7: ; Lösche aktuelles Highlight auf Pin, Name oder Type-Feld 1BB7: ; 1BB7: ; in: -- 1BB7: ; out: -- 1BB7: ; mod: AF 1BB7: 1BB7: ic_hilight_row_col data 0 ; for ld bc,(ic_hilight_row_col) 1BB7: ic_hilight_col data 1 1BB7: ic_hilight_row data 1 1BB7: ic_hilight_size_attr data 0 ; for ld de,(ic_hilight_size_attr) 1BB7: ic_hilight_size data 1 1BB7: ic_hilight_attr data 1 1BB7: 1BB7: ic_clear_hilight: 1BB7: D9 exx 1BB8: 1BB8: ED5BA35C ld de,(ic_hilight_size_attr) ; d=attr, e=size 1BBC: AF xor a 1BBD: BB cp e 1BBE: 280F jr z,icca3 1BC0: 32A35C ld (ic_hilight_size),a ; ic_hilight_size := 0 1BC3: ED4BA15C ld bc,(ic_hilight_row_col) ; b=row, c=col 1BC7: 1BC7: CD390E call calc_attr_hl_for_row_b_col_c ; pres bc, de 1BCA: 1BCA: 72 icca1 ld (hl),d ; clear field with old attr 1BCB: 2C inc l 1BCC: 1D dec e 1BCD: 20FB jr nz,icca1 1BCF: 1BCF: D9 icca3 exx 1BD0: C9 ret 1BD1: 1BD1: 1BD1: ; -------------------------------------------------------- 1BD1: ; Setze Highlight auf Pin, Name oder Type-Feld 1BD1: ; 1BD1: ; in: B = row 1BD1: ; C = col 1BD1: ; out: -- 1BD1: ; mod: 1BD1: 1BD1: ic_set_hilight: 1BD1: CD1B1C call ic_validate_hilight ; -> e = size 1BD4: CDB71B call ic_clear_hilight ; clear old 1BD7: CD390E call calc_attr_hl_for_row_b_col_c ; hl -> attr ((pres. bcde)) 1BDA: 56 ld d,(hl) ; d = old attr 1BDB: 1BDB: ; set hilight: 1BDB: 7B ld a,e ; a = size 1BDC: 36FA icsh1 ld (hl),flashing+bright+red+white_paper 1BDE: 23 inc hl 1BDF: 3D dec a 1BE0: 20FA jr nz,icsh1 1BE2: 1BE2: ; update ic_hilight: 1BE2: ED43A15C ld (ic_hilight_row_col),bc 1BE6: ED53A35C ld (ic_hilight_size_attr),de 1BEA: C9 ret 1BEB: 1BEB: 1BEB: #if 0 1BEB: ; -------------------------------------------------------- 1BEB: ; Setze Hilight auf ein obit 1BEB: ; 1BEB: ; in: A = pin no. [0..47] 1BEB: ; out: -- 1BEB: ; mod: AF 1BEB: 1BEB: ic_set_hilight_on_obit: 1BEB: 1BEB: ld b,a ; row = pin 1BEB: ld c,ic_col_lout ; col 1BEB: cp 24 1BEB: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1BEB: ld c,ic_col_rout ; col 1BEB: cpl 1BEB: add 48 1BEB: jr ic_set_hilight 1BEB: 1BEB: 1BEB: 1BEB: ; -------------------------------------------------------- 1BEB: ; Setze Hilight auf ein type feld 1BEB: ; 1BEB: ; in: A = pin no. [0..47] 1BEB: ; out: -- 1BEB: ; mod: AF, AF' 1BEB: 1BEB: ic_set_hilight_on_type: 1BEB: ld b,a ; row = pin 1BEB: ld c,ic_col_ltype ; col 1BEB: cp 24 1BEB: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1BEB: ld c,ic_col_rtype ; col 1BEB: cpl 1BEB: add 48 1BEB: jr ic_set_hilight 1BEB: 1BEB: 1BEB: 1BEB: ; -------------------------------------------------------- 1BEB: ; Setze Hilight auf ein name feld 1BEB: ; 1BEB: ; in: A = pin no. [0..47] 1BEB: ; out: -- 1BEB: ; mod: AF 1BEB: 1BEB: ic_set_hilight_on_name: 1BEB: ld b,a ; row = pin 1BEB: ld c,ic_col_lname ; col 1BEB: cp 24 1BEB: jr c,ic_set_hilight ; wenn pin<24 ~ linke Seite 1BEB: ld c,ic_col_rname ; col 1BEB: cpl 1BEB: add 48 1BEB: jr ic_set_hilight 1BEB: #endif 1BEB: 1BEB: 1BEB: ; -------------------------------------------------------- 1BEB: ; Validate data for pin field 1BEB: ; 1BEB: ; in: B=row 1BEB: ; C=col 1BEB: ; out: B = row 1BEB: ; C = vol 1BEB: ; E = field size 1BEB: ; mod: AF, BC, E 1BEB: 1BEB: 01020200 1BEF: 04040404 1BF3: 04040404 1BF7: 00020201 ic_size_tab defb 1,2,2,0,4,4,4,4, 4,4,4,4,0,2,2,1 1BFB: 10111111 1BFF: 14141414 ic_col0_tab defb $10,$11,$11,$11,$14,$14,$14,$14 ; col0 der jeweiligen felder 1C03: 18181818 1C07: 181D1D1F defb $18,$18,$18,$18,$18,$1d,$1d,$1f 1C0B: 11141414 1C0F: 18181818 ic_next_tab defb $11,$14,$14,$14,$18,$18,$18,$18 ; col0 des nächsten feldes 1C13: 1D1D1D1D 1C17: 1D1F1F10 defb $1d,$1d,$1d,$1d,$1d,$1f,$1f,$10 1C1B: 1C1B: ic_validate_hilight: 1C1B: E5 push hl 1C1C: CD3F1C call ic_validate_row 1C1F: CD321C call ic_validate_col 1C22: CD271C call ic_get_size_for_col 1C25: E1 pop hl 1C26: C9 ret 1C27: 1C27: ic_get_size_for_col: 1C27: 21DB1B ld hl,ic_size_tab-16 1C2A: 79 ld a,c 1C2B: 85 add l 1C2C: 6F ld l,a 1C2D: 5E ld e,(hl) 1C2E: D0 ret nc 1C2F: 24 inc h 1C30: 5E ld e,(hl) 1C31: C9 ret 1C32: 1C32: ic_validate_col: 1C32: 21FB1B ld hl,ic_col0_tab 1C35: 79 ld a,c 1C36: E60F and $0F 1C38: 85 add l 1C39: 6F ld l,a 1C3A: 4E ld c,(hl) 1C3B: D0 ret nc ; <- cy vom 'add l' 1C3C: 24 inc h 1C3D: 4E ld c,(hl) 1C3E: C9 ret 1C3F: 1C3F: ic_validate_row: 1C3F: 3A375B ld a,(io_pins) 1C42: A7 and a 1C43: 2002 jr nz,$+4 1C45: 3E30 ld a,48 ; wenn pins=0 dann volle Höhe zulassen 1C47: 0F rrca 1C48: 3D dec a ; a = max 1C49: B8 cp b 1C4A: D0 ret nc ; ret if b is in range 1C4B: CB78 bit 7,b ; test sign to determine side of overflow 1C4D: 47 ld b,a 1C4E: C0 ret nz ; nz => neg => b < 0 => b := max 1C4F: 0600 ld b,0 ; z => pos => b > max => b := 0 1C51: C9 ret 1C52: 1C52: 1C52: 1C52: ; -------------------------------------------------------- 1C52: ; clear hilight on current cell (if any) 1C52: ; and move down to next cell 1C52: 1C52: ic_move_hilight_down: 1C52: 3E06 ld a,keycode_down 1C54: ;jr ic_move_hilight 1C54: 1C54: 1C54: 1C54: ; -------------------------------------------------------- 1C54: ; clear hilight on current cell (if any) 1C54: ; and advance according to key in A 1C54: 1C54: ic_move_hilight: 1C54: ED4BA15C ld bc,(ic_hilight_row_col) ; b=row, c=col 1C58: 1C58: 21D11B ld hl,ic_set_hilight ; preset return address 1C5B: E5 push hl 1C5C: 1C5C: FE07 cp keycode_up 1C5E: 281D jr z,ic_up 1C60: FE06 cp keycode_down 1C62: 281B jr z,ic_down 1C64: FE08 cp keycode_right 1C66: 281B jr z,ic_right 1C68: FE05 cp keycode_left 1C6A: 2815 jr z,ic_left 1C6C: 1C6C: FE37 cp '7' 1C6E: 280D jr z,ic_up 1C70: FE36 cp '6' 1C72: 280B jr z,ic_down 1C74: FE38 cp '8' 1C76: 280B jr z,ic_right 1C78: FE35 cp '5' 1C7A: 2805 jr z,ic_left 1C7C: 1C7C: C9 ret ; error 1C7D: 1C7D: 05 ic_up dec b 1C7E: C9 ret 1C7F: 1C7F: 04 ic_down inc b 1C80: C9 ret 1C81: 1C81: 0D ic_left dec c 1C82: C9 ret 1C83: 1C83: ic_right 1C83: 21FB1B ld hl,ic_next_tab-$10 1C86: 79 ld a,c 1C87: 85 add a,l 1C88: 6F ld l,a 1C89: 4E ld c,(hl) 1C8A: D0 ret nc 1C8B: 24 inc h 1C8C: 4E ld c,(hl) 1C8D: C9 ret 1C8E: 1C8E: 1C8E: 1C8E: ; -------------------------------------------------------- 1C8E: ; Init / Start / Stop IC-Grafik 1C8E: ; Data-Bereich muss bei Systemstart genullt werden. 1C8E: ; 1C8E: ; in: -- 1C8E: ; out: -- 1C8E: ; mod: -- 1C8E: 1C8E: init_pin_display: 1C8E: stop_pin_display: 1C8E: E5 push hl 1C8F: 21385B ld hl,io_flags 1C92: CBBE res io_flag_irpt,(hl) ; disable Grafik 1C94: E1 pop hl 1C95: C9 ret 1C96: 1C96: start_pin_display: 1C96: F5 push af 1C97: CDB61C call ic_detect_size 1C9A: F1 pop af 1C9B: ;jr resume_pin_display 1C9B: 1C9B: resume_pin_display: 1C9B: E5 push hl 1C9C: 21385B ld hl,io_flags 1C9F: CBFE set io_flag_irpt,(hl) ; enable Grafik 1CA1: E1 pop hl 1CA2: ;jr ic_force_redraw 1CA2: 1CA2: 1CA2: 1CA2: ; -------------------------------------------------------- 1CA2: ; Erzwinge Neuanzeige der Grafik 1CA2: ; 1CA2: ; Die Grafik wird auch sofort einmal ausgegeben, 1CA2: ; damit die Updateroutine aufgerufen wird, solange noch alle 1CA2: ; neuen Bytes != die alten Bytes sind. 1CA2: ; 1CA2: ; in: -- 1CA2: ; out: -- 1CA2: ; mod: -- 1CA2: 1CA2: ic_force_redraw: 1CA2: D9 exx 1CA3: F5 push af 1CA4: 1CA4: 21395B ld hl,io_bits_table 1CA7: 060C ld b,io_bits_table_size / 2 1CA9: 1CA9: 7E icfr1 ld a,(hl) ; a = new state 1CAA: 23 inc hl 1CAB: 2F cpl 1CAC: 77 ld (hl),a ; old_state := ~new_state => redraw 1CAD: 23 inc hl 1CAE: 10F9 djnz icfr1 1CB0: 1CB0: CD651E call ic_update_all_pins_no_exx 1CB3: 1CB3: F1 pop af 1CB4: D9 exx 1CB5: C9 ret 1CB6: 1CB6: 1CB6: 1CB6: ; -------------------------------------------------------- 1CB6: ; Ermittle Pinzahl des eingesetzten ICs: 1CB6: ; 1CB6: ; Ann.: Corner pinning 1CB6: ; Der Pin links-unten muss fest auf 0 liegen 1CB6: ; Setzt io_pins entsprechend 1CB6: ; 1CB6: ; in: -- 1CB6: ; out: a = io_pins 1CB6: ; mod: af 1CB6: 1CB6: ic_detect_size: 1CB6: CDE21D call ic_switch_vcc_off ; all pins -> 0 1CB9: C5 push bc 1CBA: 0618 ld b,24 1CBC: 1CBC: 78 icds1 ld a,b 1CBD: 3D dec a 1CBE: CDFA1C call ic_set_pin ; set pin to 1 1CC1: 78 ld a,b 1CC2: 3D dec a 1CC3: CDD31C call ic_get_pin ; read pin back 1CC6: 2802 jr z,icds2 ; ground jumper found 1CC8: 10F2 djnz icds1 1CCA: 1CCA: ; ground jumper found (n>0) or not found (n=0) => set io_pins 1CCA: 78 icds2 ld a,b 1CCB: 87 add a ; *2 1CCC: 32375B ld (io_pins),a 1CCF: 1CCF: C1 pop bc 1CD0: C3E21D jp ic_switch_vcc_off ; alle pins wieder 0 1CD3: 1CD3: 1CD3: 1CD3: ; --------------------------------------------- 1CD3: ; Read pin from test socket 1CD3: ; 1CD3: ; Liest das Bit sofort direkt vom Testsockel 1CD3: ; aktualisiert io_bits_table[byte].in.new 1CD3: ; 1CD3: ; Anm.: Normalerweise sollte man io_sync_ibits aufrufen 1CD3: ; und danach alle Pin-States nur noch aus der Tabelle lesen. 1CD3: ; 1CD3: ; in: a = pin no. [0..47] 1CD3: ; out: z = z/nz = 0/1 1CD3: ; mod: af 1CD3: 1CD3: 1CD3: ic_get_pin: 1CD3: D9 exx 1CD4: 1CD4: CD201D call ic_calc_ahlbc_for_pin_a_no_exx 1CD7: 23 inc hl 1CD8: 23 inc hl ; -> io_bits_table[byte].in.new 1CD9: ED48 in c,(c) 1CDB: 71 ld (hl),c 1CDC: 1CDC: A1 and c ; ret z/nz 1CDD: 1CDD: D9 exx 1CDE: C9 ret 1CDF: 1CDF: 1CDF: 1CDF: ; --------------------------------------------- 1CDF: ; Set pin on test socket acc. to cy-flag 1CDF: ; 1CDF: ; Schreibt das Bit umgehend zum Testsockel 1CDF: ; Die restlichen Bits des betroffenen Bytes werden aus 1CDF: ; der io_bits_table[].out.new gelesen. Dieses Byte 1CDF: ; wird danach auch aktualisiert. 1CDF: ; 1CDF: ; Anm.: Wenn viele Pins geändert werden sollen, ist es besser, 1CDF: ; diese in io_bits_table[].out.new zu ändern und danach 1CDF: ; io_sync_obits und dann auch io_sync_ibits aufzurufen. 1CDF: ; 1CDF: ; in: a = pin no. [0..47] 1CDF: ; f = c/nc => set/reset 1CDF: ; out: -- 1CDF: ; mod: af 1CDF: 1CDF: ic_set_pin_to_cy: 1CDF: 3819 jr c,ic_set_pin 1CE1: ;jr ic_reset_pin 1CE1: 1CE1: 1CE1: 1CE1: ; --------------------------------------------- 1CE1: ; set/clear/toggle usw. pin a 1CE1: ; 1CE1: ; ic_reset_pin set pin a to 0 1CE1: ; ic_set_pin set pin a to 1 1CE1: ; ic_toggle_pin toggle pin a 0 <-> 1 1CE1: ; ic_trigger_pin double toggle (0-1-0 or 1-0-1 dep. on current state) 1CE1: ; 1CE1: ; in: a = pin no. [0..47] 1CE1: ; out: -- 1CE1: ; mod: af 1CE1: 1CE1: ic_reset_current_pin: 1CE1: CD951B call calc_pin_from_hilight 1CE4: 21411D ld hl,io_sync_ibits 1CE7: E5 push hl 1CE8: 1CE8: ic_reset_pin: 1CE8: D9 exx 1CE9: CD201D call ic_calc_ahlbc_for_pin_a_no_exx 1CEC: 2F cpl ; bmask -> nmask 1CED: A6 and (hl) 1CEE: 77 ics1: ld (hl),a 1CEF: ED79 ics2: out (bc),a 1CF1: D9 exx 1CF2: C9 ret 1CF3: 1CF3: ic_set_current_pin: 1CF3: CD951B call calc_pin_from_hilight 1CF6: 21411D ld hl,io_sync_ibits 1CF9: E5 push hl 1CFA: 1CFA: ic_set_pin: 1CFA: D9 exx 1CFB: CD201D ics3 call ic_calc_ahlbc_for_pin_a_no_exx 1CFE: B6 or (hl) 1CFF: 18ED jr ics1 1D01: 1D01: ic_toggle_current_pin: 1D01: CD951B call calc_pin_from_hilight 1D04: 21411D ld hl,io_sync_ibits 1D07: E5 push hl 1D08: 1D08: ic_toggle_pin: 1D08: D9 exx 1D09: CD201D call ic_calc_ahlbc_for_pin_a_no_exx 1D0C: AE xor (hl) 1D0D: 18DF jr ics1 1D0F: 1D0F: ic_trigger_current_pin: 1D0F: CD951B call calc_pin_from_hilight 1D12: 21411D ld hl,io_sync_ibits 1D15: E5 push hl 1D16: 1D16: ic_trigger_pin: 1D16: D9 exx 1D17: CD201D call ic_calc_ahlbc_for_pin_a_no_exx 1D1A: AE xor (hl) ; toggle 1D1B: ED79 out (bc),a 1D1D: 7E ld a,(hl) ; toggle 1D1E: 18CF jr ics2 1D20: 1D20: 1D20: 1D20: ; ---------------------------------------------- 1D20: ; Calculate parameters for accessing pin a: 1D20: ; 1D20: ; in: a = pin no [0..47] 1D20: ; out: a = mask for bit 1D20: ; bc = io address for byte 1D20: ; hl -> io_bits_table[byte].out.new 1D20: ; mod: af, bc, de, hl 1D20: 1D20: ic_calc_ahlbc_for_pin_a_no_exx: 1D20: ic_calc_ahlbc_for_pin_a: 1D20: 1D20: 47 ld b,a ; a = b = pin no. 1D21: 1D21: ; calc bit mask: 1D21: E607 and 7 ; a = bit no. 1D23: 219F1F ld hl,bmasks 1D26: 85 add a,l 1D27: 6F ld l,a 1D28: 4E ld c,(hl) ; c = bit mask for bit 1D29: 1D29: ; calc offset in io table 1D29: 78 ld a,b ; a = b = pin no. 1D2A: E638 and $38 ; a = byte no. * 8 1D2C: 0F rrca ; a = byte no. * 4 1D2D: 1600 ld d,0 1D2F: 5F ld e,a ; de = offset in io table 1D30: 1D30: ; calc io sub address 1D30: 0F rrca 1D31: 0F rrca ; a = byte no. 1D32: ;ld h,nmasks/256 == bmasks/256 1D32: C6A7 add a,nmasks%256 1D34: 6F ld l,a 1D35: 46 ld b,(hl) ; b = io sub addr 1D36: 1D36: ; final 1D36: 21395B ld hl,io_bits_table 1D39: 19 add hl,de ; hl -> io_bits_table[byte] 1D3A: 1D3A: 79 ld a,c ; a = bit mask for bit 1D3B: 0EEF ld c,port ; bc = io addr 1D3D: C9 ret 1D3E: 1D3E: 1D3E: 1D3E: ; --------------------------------------------- 1D3E: ; write io_bits_table[].out.new to tester and 1D3E: ; read io_bits_table[].in.new from tester 1D3E: ; 1D3E: ; in: -- 1D3E: ; out: -- 1D3E: ; mod: af 1D3E: 1D3E: io_sync_iobits: 1D3E: CD551D call io_sync_obits 1D41: ; jr io_sync_ibits 1D41: 1D41: 1D41: 1D41: ; --------------------------------------------- 1D41: ; read io_bits_table[].in.new from tester 1D41: ; 1D41: ; in: -- 1D41: ; out: -- 1D41: ; mod: af 1D41: 1D41: io_sync_ibits: 1D41: D9 exx 1D42: 1D42: 214F5B ld hl,io_bits_table + io_bits_data_size*5 + io_offset_in + io_offset_new 1D45: 11FCFF ld de,-io_bits_data_size 1D48: 01EFDF ld bc,port_A13 1D4B: 1D4B: ED78 isi1 in a,(c) 1D4D: 77 ld (hl),a 1D4E: 19 add hl,de 1D4F: CB08 rrc b 1D51: 38F8 jr c,isi1 1D53: 1D53: D9 exx 1D54: C9 ret 1D55: 1D55: 1D55: 1D55: ; --------------------------------------------- 1D55: ; write io_bits_table[].out.new to tester 1D55: ; 1D55: ; in: -- 1D55: ; out: -- 1D55: ; mod: af 1D55: 1D55: io_sync_obits: 1D55: D9 exx 1D56: 1D56: 214D5B ld hl,io_bits_table + io_bits_data_size*5 + io_offset_out + io_offset_new 1D59: 11FCFF ld de,-io_bits_data_size 1D5C: 01EFDF ld bc,port_A13 1D5F: 1D5F: 7E iso1 ld a,(hl) 1D60: ED79 out (bc),a 1D62: 19 add hl,de 1D63: CB08 rrc b 1D65: 38F8 jr c,iso1 1D67: 1D67: D9 exx 1D68: C9 ret 1D69: 1D69: 1D69: 1D69: ; --------------------------------------------- 1D69: ; Prüfe, ob der Tester antwortet 1D69: ; 1D69: ; in: -- 1D69: ; out: a = error code: 0=ok 1D69: ; f = z/nz = ok/error 1D69: ; mod: af 1D69: 1D69: ic_test_tester_present: 1D69: CDE21D call ic_switch_vcc_off ; -> all pins 0 1D6C: 76 halt ; if no tester attached, then we might read ula bytes 1D6D: ; => wait until ula out of screen$ area 1D6D: CD411D call io_sync_ibits ; -> io_bits_table[].in.new sollte jetzt nur Nullen enthalten 1D70: 1D70: D9 exx 1D71: 213B5B ld hl,io_bits_table+io_offset_in+io_offset_new 1D74: 110400 ld de,io_bits_data_size 1D77: 0606 ld b,6 ; 6 table cells 1D79: 97 sub a 1D7A: 1D7A: B6 iso3 or (hl) ; table[].in.new = 0 ? 1D7B: 2006 jr nz,iso4 1D7D: 19 add hl,de 1D7E: 10FA djnz iso3 1D80: 1D80: ; 6x $00 -> ok! 1D80: D9 exx 1D81: A7 and a ; ret z 1D82: C9 ret 1D83: 1D83: ; byte != $00 -> error 1D83: F5 iso4 push af ; sp: the byte 1D84: FEFF cp 255 1D86: 200E jr nz,iso5 ; byte is not $FF 1D88: 3E06 ld a,6 1D8A: 90 sub b 1D8B: 2009 jr nz,iso5 ; abort not at first byte => tester present but broken 1D8D: F1 pop af ; drop 1D8E: 1D8E: ; Abort beim 1. Byte mit Wert $FF: 1D8E: ; dann wahrscheinlich kein Tester dran 1D8E: 3E03 ld a,error_notester 1D90: 322E5B ld (errno),a 1D93: A7 and a ; ret nz 1D94: D9 exx 1D95: C9 ret 1D96: 1D96: 1D96: ; Tester seems to respond, but not all bits read back are '0': 1D96: 3E06 iso5 ld a,6 1D98: 90 sub b ; b=6 <=> A8 ... b=1 <=> A13 responds != $00 1D99: F5 iso55 push af ; sp: pin group number [0..5] 1D9A: 21BB1D ld hl,msg_tester_broken 1D9D: CD3917 call set_error_message ; hl -> data 1DA0: E5 push hl 1DA1: FDE1 pop iy 1DA3: ; patch error msg: 1DA3: F1 pop af ; pin group 1DA4: C630 add '0' 1DA6: FD770A ld (IY+msg_tester_broken_group),a 1DA9: F1 pop af ; the byte 1DAA: 47 ld b,a 1DAB: CD591F call calc_hex_char 1DAE: FD771C ld (IY+msg_tester_broken_lo),a 1DB1: 78 ld a,b 1DB2: CD551F call calc_hex_char_hi 1DB5: FD771B ld (IY+msg_tester_broken_hi),a 1DB8: A7 and a ; ret nz 1DB9: D9 exx 1DBA: C9 ret 1DBB: 1DBB: 50696E20 1DBF: 67726F75 1DC3: 70205820 1DC7: 72657370 1DCB: 6F6E6473 1DCF: 20776974 1DD3: 68202458 1DD7: 582E00 msg_tester_broken defm "Pin group X responds with $XX.",0 1DDA: msg_tester_broken_group equ 10 ; offset inside msg 1DDA: msg_tester_broken_lo equ 28 ; offset inside msg 1DDA: msg_tester_broken_hi equ 27 ; offset inside msg 1DDA: 1DDA: 1DDA: 1DDA: ; --------------------------------------------- 1DDA: ; Switch Tester on: 1DDA: ; set pin_47 (Vcc) to 1 1DDA: ; 1DDA: ; in: -- 1DDA: ; out: -- 1DDA: ; mod: af 1DDA: 1DDA: ic_switch_vcc_on: 1DDA: 3E2F ld a,47 1DDC: CDFA1C call ic_set_pin 1DDF: C3411D jp io_sync_ibits 1DE2: 1DE2: 1DE2: 1DE2: ; --------------------------------------------- 1DE2: ; Switch Tester off: 1DE2: ; set all pins to 0 1DE2: ; 1DE2: ; in: -- 1DE2: ; out: -- 1DE2: ; mod: af 1DE2: 1DE2: ic_switch_vcc_off: 1DE2: D9 exx 1DE3: 1DE3: 97 sub a ; a = 0 1DE4: 01EFC0 ld bc,all_ports 1DE7: ED79 out (bc),a ; -> all off 1DE9: 1DE9: 21395B ld hl,io_bits_table+io_offset_out+io_offset_new 1DEC: 110400 ld de,io_bits_data_size 1DEF: 0606 ld b,6 ; 6 table cells 1DF1: 1DF1: 77 iso2 ld (hl),a ; table[].out.new := 0 1DF2: 19 add hl,de 1DF3: 10FC djnz iso2 1DF5: 1DF5: D9 exx 1DF6: C3411D jp io_sync_ibits 1DF9: 1DF9: 1DF9: 1DF9: 1DF9: 1DF9: 1DF9: ; ------------------------------------------------ 1DF9: ; 1DF9: ; I N T E R R U P T - R O U T I N E 1DF9: ; 1DF9: ; ------------------------------------------------ 1DF9: 1DF9: 1DF9: 1DF9: ; --------------------------------------------- 1DF9: ; Display "0" or "1" at screenbyte address hl 1DF9: ; 1DF9: ; Overwrites entire 8x8 character cell 1DF9: ; Does not set attributes 1DF9: ; 1DF9: ; in: c.bit(0) 1DF9: ; hl -> top byte of character cell 1DF9: ; out: -- 1DF9: ; mod: -- 1DF9: 1DF9: ic_render_pin_no_exx: 1DF9: ic_render_pin: 1DF9: F5 push af 1DFA: E5 push hl 1DFB: D5 push de 1DFC: 1DFC: 11111E ld de,char_0 1DFF: CB41 bit 0,c 1E01: 2802 jr z,$+4 1E03: 1E18 ld e,char_1 % 256 ; de -> char_0 or char_1 1E05: 1E05: ; 1. Byte ($00) einzeln poken 1E05: ;ld a,(de) 1E05: ;ld (hl),a 1E05: 3600 ld (hl),0 1E07: 1E07: ; dann Schleife bis erneut Byte = $00 1E07: 1C icrp1 inc e ; inc de 1E08: 24 inc h ; inc hl: row(n+1) = row(n)+256 1E09: 1A ld a,(de) 1E0A: 77 ld (hl),a 1E0B: A7 and a 1E0C: 20F9 jr nz,icrp1 ; bis unterstes Byte == $00 kopiert wurde 1E0E: 1E0E: D1 pop de 1E0F: E1 pop hl 1E10: F1 pop af 1E11: C9 ret 1E12: 1E12: #if ($-1)/256 != ($+8-1+8-1-1)/256 1E12: defs 256 - $%256 + 1 1E12: #endif 1E12: 1E12: char_0 equ $-1 1E12: ;defb %00000000 1E12: 3C defb %00111100 1E13: 46 defb %01000110 1E14: 4A defb %01001010 1E15: 52 defb %01010010 1E16: 62 defb %01100010 1E17: 3C defb %00111100 1E18: 00 defb %00000000 1E19: 1E19: char_1 equ $-1 1E19: ;defb %00000000 1E19: 18 defb %00011000 1E1A: 38 defb %00111000 1E1B: 58 defb %01011000 1E1C: 18 defb %00011000 1E1D: 18 defb %00011000 1E1E: 7E defb %01111110 1E1F: 00 defb %00000000 1E20: 1E20: 1E20: 1E20: ; --------------------------------------------- 1E20: ; Display "0" or "1" for group of 8 pins 1E20: ; Renders only changed bits 1E20: ; Uses rr to advance bit => used for leftside columns 1E20: ; 1E20: ; in: hl -> io_pins table cell 1E20: ; de -> screenbyte 1E20: ; a = valid bits mask 1E20: ; out: hl -> next cell = hl+2 1E20: ; mod: af 1E20: 1E20: ic_render_8_pins_left_no_exx: 1E20: ic_render_8_pins_left: 1E20: C5 push bc 1E21: D5 push de 1E22: 1E22: 47 ld b,a ; b = valid bits 1E23: 4E ld c,(hl) ; c = new value 1E24: 23 inc hl 1E25: 7E ld a,(hl) ; a = old value 1E26: 71 ld (hl),c ; update old value cell 1E27: 23 inc hl 1E28: E5 push hl 1E29: 1E29: A9 xor c ; a = old ^ new = changed bits 1E2A: A0 and b ; a = valid pins only & cy=0 1E2B: EB ex hl,de ; hl -> screenbyte 1E2C: 112000 ld de,32 ; de = screen row offset 1E2F: 1803 jr icr1 1E31: 1E31: CB19 icr2 rr c ; next pin 1E33: 19 add hl,de ; next character row & cy=0 1E34: 1E34: CB1F icr1 rr a ; next 'pin changed' flag ((rr a not rra wg. z-flag)) 1E36: DCF91D call c,ic_render_pin_no_exx ; pin changed => draw it 1E39: 20F6 jr nz,icr2 ; still 'pin changed' flags set 1E3B: 1E3B: E1 pop hl 1E3C: D1 pop de 1E3D: C1 pop bc 1E3E: C9 ret 1E3F: 1E3F: 1E3F: 1E3F: ; --------------------------------------------- 1E3F: ; Display "0" or "1" for group of 8 pins 1E3F: ; Renders only changed bits 1E3F: ; Uses rl to advance bit => used for rightside columns 1E3F: ; 1E3F: ; in: hl -> io_pins table cell 1E3F: ; de -> screenbyte 1E3F: ; a = valid bits mask 1E3F: ; out: hl -> prev cell = hl-2 1E3F: ; mod: af 1E3F: 1E3F: ic_render_8_pins_right_no_exx: 1E3F: ic_render_8_pins_right: 1E3F: C5 push bc 1E40: D5 push de 1E41: E5 push hl 1E42: 1E42: 47 ld b,a ; b = valid bits 1E43: 4E ld c,(hl) ; c = new value 1E44: 23 inc hl 1E45: 7E ld a,(hl) ; a = old value 1E46: 71 ld (hl),c ; update old value cell 1E47: 1E47: A9 xor c ; a = old ^ new = changed bits 1E48: A0 and b ; a = valid pins only & cy=0 1E49: EB ex hl,de ; hl -> screenbyte 1E4A: 112000 ld de,32 ; de = screen row offset 1E4D: ED52 sbc hl,de 1E4F: 1E4F: CB01 icr4 rlc c ; next pin -> bit 0 1E51: 19 add hl,de ; next character row & cy=0 1E52: 1E52: CB17 rl a ; next 'pin changed' flag ((rl a not rla wg. z-flag)) 1E54: DCF91D call c,ic_render_pin ; pin changed => draw it 1E57: 20F6 jr nz,icr4 ; still 'pin changed' flags set 1E59: 1E59: E1 pop hl 1E5A: D1 pop de 1E5B: C1 pop bc 1E5C: 2B dec hl 1E5D: 2B dec hl 1E5E: C9 ret 1E5F: 1E5F: 1E5F: 1E5F: ; -------------------------------------------------------- 1E5F: ; Interruptroutine 1E5F: ; 1E5F: ; Update displayed state if IC pins 1E5F: ; Renders changed pins only 1E5F: ; draws io_pins/2 pins per side 1E5F: ; draws 4 columns in total: 1E5F: ; left side: out state to test socket 1E5F: ; left side: in state from test socket 1E5F: ; right side: in state from test socket 1E5F: ; right side: out state to test socket 1E5F: ; Uses data from io_pins table only 1E5F: ; Does not actually read state from tester 1E5F: ; 1E5F: ; in: -- 1E5F: ; out: -- 1E5F: ; mod: af, bc, de, hl 1E5F: 1E5F: irpt_pin_display: 1E5F: 3A385B ld a,(io_flags) 1E62: CB7F bit io_flag_irpt,a 1E64: C8 ret z 1E65: ;jr ic_update_all_pins 1E65: 1E65: 1E65: 1E65: ; --------------------------------------------- 1E65: ; Update all 4 pin display columns 1E65: ; Renders only changed bits 1E65: ; 1E65: ; in: -- 1E65: ; out: -- 1E65: ; mod: af, bc, de, hl 1E65: 1E65: ic_update_all_pins_no_exx: 1E65: ic_update_all_pins: 1E65: 1E65: 3A375B ld a,(io_pins) 1E68: CB2F sra a ; a = pins per side 1E6A: C8 ret z ; pins = 0 1E6B: 1E6B: 014F5B ld bc,io_bits_r +io_offset_in +io_bits_data_size*2 ; bc -> right side table, last cell 1E6E: 21395B ld hl,io_bits_l +io_offset_out ; hl -> left side table, first cell 1E71: 1E71: 1640 ld d,$40 ; de -> screen, start of upper block 1E73: 1E73: C5 icr5 push bc ; (sp) -> rightside table cells 1E74: 1E74: 4F ld c,a ; a = c = remaining pins 1E75: CD931F call calc_rmask 1E78: 47 ld b,a ; a = b = mask 1E79: 1E79: 1E10 ld e,ic_col_lout ; de -> screenbyte 1E7B: CD201E call ic_render_8_pins_left_no_exx ; hl+=2 1E7E: 1E7E: 78 ld a,b ; a = mask 1E7F: 1E13 ld e,ic_col_lin ; de -> screenbyte 1E81: CD201E call ic_render_8_pins_left_no_exx ; hl+=2 1E84: 1E84: E3 ex hl,(sp) ; hl -> rightside table cells 1E85: 1E85: 79 ld a,c ; a = c = remaining pins 1E86: CD8B1F call calc_lmask 1E89: 47 ld b,a ; a = b = mask 1E8A: 1E8A: 1E1C ld e,ic_col_rin ; de -> screenbyte 1E8C: CD3F1E call ic_render_8_pins_right_no_exx ; hl-=2 1E8F: 1E8F: 78 ld a,b ; a = mask 1E90: 1E1F ld e,ic_col_rout ; de -> screenbyte 1E92: CD3F1E call ic_render_8_pins_right_no_exx ; hl-=2 1E95: 1E95: E3 ex hl,(sp) ; hl -> leftside table cells 1E96: 1E96: 7A ld a,d 1E97: C608 add 8 1E99: 57 ld d,a ; de -> next screen block 1E9A: 1E9A: 79 ld a,c 1E9B: D608 sub 8 ; a = remaining pins 1E9D: 1E9D: C1 pop bc 1E9E: C8 ret z ; remaining pins = 0 1E9F: 30D2 jr nc,icr5 ; remaining pins > 0 1EA1: C9 ret ; remaining pins < 0 1EA2: 1EA2: 1EA2: 1EA2: 1EA2: 1EA2: 1EA2: 1EA2: #include "pin display.ass" 1EA2: 1EA2: 1EA2: 1EA2: ; -------------------------------------------------------- 1EA2: ; System Timer: 1EA2: ; 2 bytes overflow after approx. 22 min. 1EA2: 1EA2: timer_cell data 3 1EA2: 1EA2: 1EA2: 1EA2: ; -------------------------------------------------------- 1EA2: ; Initialisierung: No Action 1EA2: ; Ann.: Data-Bereich wird bei Systemstart genullt. 1EA2: ; 1EA2: ; in: -- 1EA2: ; out: -- 1EA2: ; mod: -- 1EA2: 1EA2: init_timer: 1EA2: C9 ret 1EA3: 1EA3: 1EA3: 1EA3: ; -------------------------------------------------------- 1EA3: ; Interruptroutine 1EA3: ; 1EA3: ; in: -- 1EA3: ; out: -- 1EA3: ; mod: hl, f 1EA3: 1EA3: irpt_timer: 1EA3: 21A55C ld hl,timer_cell 1EA6: 34 inc (hl) 1EA7: C0 ret nz 1EA8: 23 inc hl 1EA9: 34 inc (hl) 1EAA: C0 ret nz 1EAB: 23 inc hl 1EAC: 34 inc (hl) 1EAD: C9 ret 1EAE: 1EAE: 1EAE: #include "timer.ass" 1EAE: 1EAE: ; -------------------------------------------------------- 1EAE: ; Utilities 1EAE: ; -------------------------------------------------------- 1EAE: 1EAE: ; ------------------------------------------------------------ 1EAE: ; count 0-terminated string length 1EAE: ; 1EAE: ; in: hl -> text 1EAE: ; out: hl -> text (preserved) 1EAE: ; de = size 1EAE: ; mod: af, de 1EAE: 1EAE: calc_strlen: 1EAE: 545D ld de,hl ; de = hl -> text 1EB0: 97 sub a 1EB1: BE sl1 cp (hl) 1EB2: 23 inc hl 1EB3: 20FC jr nz,sl1 1EB5: 37 scf ; hl -> behind 0 1EB6: ED52 sbc hl,de ; hl = len 1EB8: EB ex hl,de 1EB9: C9 ret 1EBA: 1EBA: 1EBA: 1EBA: 1EBA: ; ------------------------------------------------------------ 1EBA: ; print hl as decimal number with auto-sized field width 1EBA: ; 1EBA: ; vzdecstr prints with sign 1EBA: ; decstr prints unsigned 1EBA: ; 1EBA: ; in: hl = number 1EBA: ; de -> text buffer 1EBA: ; out: de++ 1EBA: ; mod: af,bc,de,hl 1EBA: 1EBA: vzdecstr: 1EBA: CB7C bit 7,h 1EBC: 280B jr z,decstr 1EBE: 3E2D ld a,'-' 1EC0: 12 ld (de),a 1EC1: 13 inc de 1EC2: 1EC2: 7C ld a,h 1EC3: 2F cpl 1EC4: 67 ld h,a 1EC5: 7D ld a,l 1EC6: 2F cpl 1EC7: 6F ld l,a 1EC8: 23 inc hl 1EC9: 1EC9: decstr: 1EC9: 011027 ld bc,10000 ; print auto-sized 1-5 characters 1ECC: A7 and a 1ECD: ED42 sbc hl,bc 1ECF: 09 add hl,bc 1ED0: 301D jr nc,decstr5 1ED2: 1ED2: 01E803 ld bc,1000 1ED5: A7 and a 1ED6: ED42 sbc hl,bc 1ED8: 09 add hl,bc 1ED9: 301A jr nc,decstr4 1EDB: 1EDB: decstr_max3digits: 1EDB: 016400 ld bc,100 1EDE: A7 and a 1EDF: ED42 sbc hl,bc 1EE1: 09 add hl,bc 1EE2: 3017 jr nc,decstr3 1EE4: 1EE4: 010A00 ld bc,10 1EE7: A7 and a 1EE8: ED42 sbc hl,bc 1EEA: 09 add hl,bc 1EEB: 3014 jr nc,decstr2 1EED: 1818 jr decstr1 1EEF: 1EEF: 1EEF: ; ------------------------------------------------------------ 1EEF: ; print unsigned decimal number with fixed amount of digits 1EEF: ; the number must actually fit in the requested field width, 1EEF: ; else strange letters are printed. 1EEF: ; 1EEF: ; decstr[1..5]: print hl with fixed field width 1..5 digits 1EEF: ; 1EEF: ; in: hl = number 1EEF: ; de->text buffer 1EEF: ; out: de++ 1EEF: ; mod: af, bc, de, hl 1EEF: 1EEF: decstr5 1EEF: 011027 ld bc,10000 ; print 5 characters wide 1EF2: CD0A1F call ds 1EF5: decstr4 1EF5: 01E803 ld bc,1000 ; print 4 characters wide 1EF8: CD0A1F call ds 1EFB: decstr3 1EFB: 016400 ld bc,100 ; print 3 characters wide 1EFE: CD0A1F call ds 1F01: decstr2 1F01: 010A00 ld bc,10 ; print 2 characters wide 1F04: CD0A1F call ds 1F07: decstr1 1F07: 010100 ld bc,1 ; print 1 character wide 1F0A: 1F0A: 3E2F ds ld a,'0'-1 1F0C: A7 and a 1F0D: 3C ds1 inc a 1F0E: ED42 sbc hl,bc 1F10: 30FB jr nc,ds1 1F12: 09 add hl,bc 1F13: 12 ld (de),a 1F14: 13 inc de 1F15: C9 ret 1F16: 1F16: 1F16: 1F16: ; ------------------------------------------------------------ 1F16: ; print word as 4 hex chars 1F16: ; 1F16: ; in: hl = number 1F16: ; de->text buffer 1F16: ; out: de++ 1F16: ; mod: af 1F16: 1F16: hexstr4: 1F16: E5 push hl 1F17: 7C ld a,h 1F18: CD1D1F call hexstr2 1F1B: E1 pop hl 1F1C: 7D ld a,l 1F1D: ;jr hexstr2 1F1D: 1F1D: 1F1D: 1F1D: ; ------------------------------------------------------------ 1F1D: ; print byte as 2 hex chars 1F1D: ; 1F1D: ; in: a = number 1F1D: ; de->text buffer 1F1D: ; out: de++ 1F1D: ; mod: af,de 1F1D: 1F1D: hexstr2: 1F1D: F5 push af 1F1E: CD241F call hexstr1hi 1F21: F1 pop af 1F22: 1804 jr hexstr1 1F24: 1F24: ; ------------------------------------------------------------ 1F24: ; print hex char for the upper nibble 1F24: ; 1F24: ; in: a = number 1F24: ; de->text buffer 1F24: ; out: de++ 1F24: ; mod: af,de 1F24: 1F24: hexstr1hi: 1F24: 1F rra 1F25: 1F rra 1F26: 1F rra 1F27: 1F rra 1F28: ;jr hexstr1 1F28: 1F28: ; ------------------------------------------------------------ 1F28: ; print hex char for the lower nibble 1F28: ; 1F28: ; in: a = number (lower nibble only) 1F28: ; de->text buffer 1F28: ; out: de++ 1F28: ; mod: af,de 1F28: 1F28: hexstr1: 1F28: E60F and $0f 1F2A: C630 add '0' 1F2C: FE3A cp '9'+1 1F2E: 3802 jr c,hs1 1F30: C607 add 7 1F32: 12 hs1 ld (de),a 1F33: 13 inc de 1F34: C9 ret 1F35: 1F35: 1F35: 1F35: ; ------------------------------------------------------------ 1F35: ; print word as 16 binary chars 1F35: ; 1F35: ; in: hl = number 1F35: ; de->text buffer 1F35: ; out: de++ 1F35: ; mod: af 1F35: 1F35: binstr16: 1F35: E5 push hl 1F36: 7C ld a,h 1F37: CD3C1F call binstr8 1F3A: E1 pop hl 1F3B: 7D ld a,l 1F3C: ;jr binstr8 1F3C: 1F3C: 1F3C: 1F3C: ; ------------------------------------------------------------ 1F3C: ; print byte as 8 binary chars 1F3C: ; 1F3C: ; in: a = number 1F3C: ; de->text buffer 1F3C: ; out: de++ 1F3C: ; mod: af 1F3C: 1F3C: binstr8: 1F3C: C5 push bc 1F3D: 0608 ld b,8 1F3F: 4F bs0 ld c,a 1F40: 3E18 bs1 ld a,'0'/2 1F42: CB11 rl c 1F44: 8F adc a,a 1F45: 12 ld (de),a 1F46: 13 inc de 1F47: 10F7 djnz bs1 1F49: C1 pop bc 1F4A: C9 ret 1F4B: 1F4B: 1F4B: 1F4B: ; ------------------------------------------------------------ 1F4B: ; print nibble as 4 binary chars 1F4B: ; 1F4B: ; in: a = number (lower nibble only) 1F4B: ; de->text buffer 1F4B: ; out: de++ 1F4B: ; mod: af 1F4B: 1F4B: binstr4: 1F4B: C5 push bc 1F4C: 0604 ld b,4 1F4E: 18EF jr bs0 1F50: 1F50: 1F50: 1F50: 1F50: 1F50: 1F50: 1F50: 1F50: ; --------------------------------------------- 1F50: ; dereference a pointer 1F50: ; 1F50: ; in: hl -> pointer or -> 2-byte value 1F50: ; out: hl = pointer or 2-byte-value 1F50: ; mod: a,hl 1F50: 1F50: deref_hl: 1F50: 7E ld a,(hl) 1F51: 23 inc hl 1F52: 66 ld h,(hl) 1F53: 6F ld l,a 1F54: C9 ret 1F55: 1F55: 1F55: 1F55: ; --------------------------------------------- 1F55: ; Convert hex value (nibble) to hex character 1F55: ; 1F55: ; in: a = lower nibble 1F55: ; out: a = char 1F55: ; mod: af 1F55: 1F55: calc_hex_char_hi: 1F55: 0F rrca 1F56: 0F rrca 1F57: 0F rrca 1F58: 0F rrca 1F59: 1F59: calc_hex_char: 1F59: E60F and $0f 1F5B: C630 add '0' 1F5D: FE3A cp '9'+1 1F5F: D8 ret c ; '0' .. '9' 1F60: C607 add 7 1F62: C9 ret ; 'A' .. 'F' 1F63: 1F63: 1F63: 1F63: ; ------------------------------------- 1F63: ; multiply: hl = b x c 1F63: ; 1F63: ; je kleiner b, desto schneller. 1F63: ; 1F63: ; in: b = n1 1F63: ; c = n2 1F63: ; out: hl 1F63: ; mod: a, bc, hl 1F63: 1F63: mult_bc: 1F63: 78 ld a,b ; a = signifikanter multiplikator 1F64: mult_ac: 1F64: 210000 ld hl,0 ; hl = ergebnis-summierer 1F67: 45 ld b,l ; bc = c = addierter multiplikator 1F68: 1F68: A7 and a ; bei a = 0 sonst kein Abbruch! 1F69: 2005 jr nz,mu1 1F6B: C9 ret 1F6C: 1F6C: mu2 ;and a ; cy muss 0 sein! 1F6C: CB11 rl c ; shift left bc 1F6E: CB10 rl b 1F70: 1F70: mu1 ;and a ; cy muss 0 sein! 1F70: 1F rra ; cy = nächsthöheres bit, a mit 0 auffüllen 1F71: 30F9 jr nc,mu2 ; da a != 0 und jetzt kein bit rausgeschiftet wurde, 1F73: ; muss immer noch mind. 1 bit in a sein 1F73: 09 add hl,bc 1F74: A7 and a ; a jetzt 0 ? 1F75: 20F5 jr nz,mu2 ; nein => weiter gehts 1F77: C9 ret ; ja => fertig 1F78: 1F78: 1F78: 1F78: ; ------------------------------------- 1F78: ; calculate mask which includes bit n 1F78: ; bit no. is masked with $07 to force legal 1F78: ; 1F78: ; calc_bmask: bits are counted from right (lsb) to left (msb) %76543210 1F78: ; calc_rbmask: bits are counted in reverse order from left to right %01234567 1F78: ; 1F78: ; in: a = bit no. 1F78: ; out: a = mask 1F78: ; mod: af 1F78: 1F78: calc_rbmask: 1F78: 2F cpl 1F79: 1F79: calc_bmask: 1F79: E607 and 7 1F7B: C69F add a,bmasks%256 1F7D: ;jr crfb2 1F7D: 1F7D: E5 crfb2 push hl ; xymasks[a] 1F7E: 261F ld h,masks/256 ; h = high byte for all masks[] 1F80: 6F ld l,a 1F81: 7E ld a,(hl) 1F82: E1 pop hl 1F83: C9 ret 1F84: 1F84: 1F84: 1F84: ; ------------------------------------- 1F84: ; calculate mask which excludes bit n 1F84: ; bit no. is masked with $07 to force legal 1F84: ; 1F84: ; calc_nmask: bits are counted from right (lsb) to left (msb) %76543210 1F84: ; calc_rnmask: bits are counted in reverse order from left to right %01234567 1F84: ; 1F84: ; in: a = bit no. 1F84: ; out: a = mask 1F84: ; mod: af 1F84: 1F84: calc_rnmask: 1F84: 2F cpl 1F85: 1F85: calc_nmask: 1F85: E607 and 7 1F87: C6A7 add a,nmasks%256 ; a < 8 => nmasks[a] 1F89: 18F2 jr crfb2 1F8B: 1F8B: 1F8B: 1F8B: ; ------------------------------------- 1F8B: ; calculate mask which includes n bits from the left (msb) 1F8B: ; if bits >= 8 then mask = $ff 1F8B: ; if bits <= 0 then mask = $00 1F8B: ; 1F8B: ; in: a = bits 1F8B: ; out: a = mask 1F8B: ; mod: af 1F8B: 1F8B: calc_lmask: 1F8B: FE08 cp 8 1F8D: 300C jr nc,crfb1 ; a≥8 / a<0 => $ff / $00 1F8F: C6AF add a,lmasks%256 ; a < 8 => lmasks[a] 1F91: 18EA jr crfb2 1F93: 1F93: 1F93: 1F93: ; ------------------------------------- 1F93: ; calculate mask which includes n bits from the right (lsb) 1F93: ; if bits >= 8 then mask = $ff 1F93: ; if bits <= 0 then mask = $00 1F93: ; 1F93: ; in: a = bits 1F93: ; out: a = mask 1F93: ; mod: af 1F93: 1F93: calc_rmask: 1F93: FE08 cp 8 1F95: 3004 jr nc,crfb1 ; a≥8 / a<0 => $ff / $00 1F97: C6B7 add a,rmasks%256 1F99: 18E2 jr crfb2 1F9B: 1F9B: 17 crfb1 rla ; cy = vz 1F9C: 9F sbc a ; mi => $ff / pl => $00 1F9D: 2F cpl ; mi => $00 / pl => $ff 1F9E: C9 ret 1F9F: 1F9F: 1F9F: 1F9F: #if $/256 != ($+32-1)/256 1F9F: defs 256 - $%256 1F9F: #endif 1F9F: 1F9F: masks: equ $ 1F9F: 01020408 1FA3: 10204080 bmasks defb $01, $02, $04, $08, $10, $20, $40, $80 1FA7: FEFDFBF7 1FAB: EFDFBF7F nmasks defb $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f 1FAF: 0080C0E0 1FB3: F0F8FCFE lmasks defb $00, $80, $c0, $e0, $f0, $f8, $fc, $fe 1FB7: 00010307 1FBB: 0F1F3F7F rmasks defb $00, $01, $03, $07, $0f, $1f, $3f, $7f 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: #if 0 1FBF: ; -------------------------------------------------------- 1FBF: ; calc. Address and bitmask for bit array 1FBF: ; 1FBF: ; in: HL -> array 1FBF: ; A = bit no. 1FBF: ; out: HL -> array[n/8] 1FBF: ; A = bitmask 1FBF: ; mod: af, hl 1FBF: 1FBF: calc_addr_hl_and_mask_a_for_bit: 1FBF: push de 1FBF: 1FBF: ld e,a ; a retten 1FBF: rrca 1FBF: rrca 1FBF: rrca 1FBF: and $1f 1FBF: add l 1FBF: jr nc,$+3 1FBF: inc h 1FBF: ld a,e ; a = pin no. 1FBF: 1FBF: ; calc_bmask: 1FBF: ld de,bmasks 1FBF: and 7 1FBF: add e 1FBF: ld e,a 1FBF: ld a,(de) 1FBF: 1FBF: pop de 1FBF: ret 1FBF: #endif 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: #if 0 1FBF: 1FBF: ; get bit number for MSB '1' in A 1FBF: ; in: a = bitarray/mask 1FBF: ; out: a = bit number [7..0] or a=-1 if a was $00 1FBF: ; mod: f 1FBF: ; 1FBF: up_get_bitno_of_msb: 1FBF: push bc 1FBF: ld b,8 1FBF: up_bn1 rlca 1FBF: jr c,up_bn2 1FBF: djnz up_bn1 1FBF: up_bn2 dec b 1FBF: ld a,b 1FBF: pop bc 1FBF: ret 1FBF: 1FBF: ; get bit number for LSB '1' in A 1FBF: ; in: a = bitarray/mask 1FBF: ; out: a = bit number [7..0] or a=8 if a was $00 1FBF: ; mod: f 1FBF: ; 1FBF: up_get_bitno_of_lsb: 1FBF: push bc 1FBF: ld b,8 1FBF: up_bn3 rrca 1FBF: jr c,up_bn4 1FBF: djnz up_bn3 1FBF: up_bn4 ld a,8 1FBF: sub b 1FBF: pop bc 1FBF: ret 1FBF: 1FBF: 1FBF: up_get_mask_for_bitno: 1FBF: and 7 1FBF: push bc 1FBF: ld bc,up_sbt 1FBF: add a,c 1FBF: ld c,a 1FBF: ld a,(bc) 1FBF: pop bc 1FBF: ret 1FBF: 1FBF: #if $/256 != ($+7)/256 1FBF: defs 256 - ($%256) 1FBF: #endif 1FBF: up_sbt defb 1,2,4,8,16,32,64,128 1FBF: 1FBF: #endif 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: 1FBF: #include "utilities.ass" 1FBF: 1FBF: 1FBF: 1FBF: vip_test 1FBF: E7 rst vip 1FC0: BF0D5649 1FC4: 50205465 1FC8: 73743A20 1FCC: 00 db print,13,"VIP Test: ",0 1FCD: 1FCD: ; ≥ 1FCD: 1FCD: 0021 db byte, 33 1FCF: 002C db byte, 44 1FD1: E3 db ge 1FD2: 300B db bra_ifnot,vt1-$ 1FD4: BF213333 1FD8: 3E3D3434 1FDC: 00 db print, "!33>=44",0 1FDD: 1FDD: 0021 vt1 db byte, 33 1FDF: 0021 db byte, 33 1FE1: E3 db ge 1FE2: 2D0B db bra_if,vt2-$ 1FE4: BF213333 1FE8: 3E3D3333 1FEC: 00 db print, "!33>=33",0 1FED: 1FED: 002C vt2 db byte, 44 1FEF: 0021 db byte, 33 1FF1: E3 db ge 1FF2: 2D0B db bra_if,vt3-$ 1FF4: BF213434 1FF8: 3E3D3333 1FFC: 00 db print, "!44>=33",0 1FFD: 1FFD: ; > 1FFD: 1FFD: 0021 vt3 db byte, 33 1FFF: 002C db byte, 44 2001: E1 db gt 2002: 300A db bra_ifnot,vt24-$ 2004: BF213333 2008: 3E343400 db print, "!33>44",0 200C: 200C: 0021 vt24 db byte, 33 200E: 00D4 db byte, -44 2010: E1 db gt 2011: 2D0B db bra_if,vt4-$ 2013: BF213333 2017: 3E2D3434 201B: 00 db print, "!33>-44",0 201C: 201C: 0021 vt4 db byte, 33 201E: 0021 db byte, 33 2020: E1 db gt 2021: 300A db bra_ifnot,vt5-$ 2023: BF213333 2027: 3E333300 db print, "!33>33",0 202B: 202B: 002C vt5 db byte, 44 202D: 0021 db byte, 33 202F: E1 db gt 2030: 2D0A db bra_if,vt6-$ 2032: BF213434 2036: 3E333300 db print, "!44>33",0 203A: 203A: ; ≤ 203A: 203A: 0021 vt6 db byte, 33 203C: 002C db byte, 44 203E: E7 db le 203F: 2D0B db bra_if,vt7-$ 2041: BF213333 2045: 3C3D3434 2049: 00 db print, "!33<=44",0 204A: 204A: 0021 vt7 db byte, 33 204C: 0021 db byte, 33 204E: E7 db le 204F: 2D0B db bra_if,vt8-$ 2051: BF213333 2055: 3C3D3333 2059: 00 db print, "!33<=33",0 205A: 205A: 002C vt8 db byte, 44 205C: 0021 db byte, 33 205E: E7 db le 205F: 300B db bra_ifnot,vt9-$ 2061: BF213434 2065: 3C3D3333 2069: 00 db print, "!44<=33",0 206A: 206A: ; < 206A: 206A: 0021 vt9 db byte, 33 206C: 002C db byte, 44 206E: E5 db lt 206F: 2D0A db bra_if,vt10-$ 2071: BF213333 2075: 3C343400 db print, "!33<44",0 2079: 2079: 0021 vt10 db byte, 33 207B: 0021 db byte, 33 207D: E5 db lt 207E: 300A db bra_ifnot,vt11-$ 2080: BF213333 2084: 3C333300 db print, "!33<33",0 2088: 2088: 002C vt11 db byte, 44 208A: 0021 db byte, 33 208C: E5 db lt 208D: 300A db bra_ifnot,vt12-$ 208F: BF213434 2093: 3C333300 db print, "!44<33",0 2097: 2097: 002100D4 209B: E3 vt12 db byte, 33, byte, -44, ge 209C: 2D0C db bra_if,vt13-$ 209E: BF213333 20A2: 3E3D2D34 20A6: 3400 db print, "!33>=-44",0 20A8: 20A8: 00D40021 20AC: E3 vt13 db byte, -44, byte, 33, ge 20AD: 300C db bra_ifnot,vt14-$ 20AF: BF212D34 20B3: 343E3D33 20B7: 3300 db print, "!-44>=33",0 20B9: 20B9: 00FF0000 20BD: E3 vt14 db byte, -1, byte, 0, ge 20BE: 300A db bra_ifnot,vt15-$ 20C0: BF212D31 20C4: 3E3D3000 db print, "!-1>=0",0 20C8: 20C8: 03008003 20CC: FF7FE3 vt15 db number, $00,$80, number, $ff,$7f, ge 20CF: 300F db bra_ifnot,vt16-$ 20D1: BF212D6D 20D5: 61783E3D 20D9: 2B6D6178 20DD: 00 db print, "!-max>=+max",0 20DE: 20DE: 03008003 20E2: FF7FE1 vt16 db number, $00,$80, number, $ff,$7f, gt 20E5: 300E db bra_ifnot,vt17-$ 20E7: BF212D6D 20EB: 61783E2B 20EF: 6D617800 db print, "!-max>+max",0 20F3: 20F3: 0021002C 20F7: 0903 vt17 db byte, 33, byte, 44, mult, number 20F9: AC05 dw 33*44 20FB: DD db eq 20FC: 2D11 db bra_if,vt18-$ 20FE: BF213333 2102: 2A34343D 2106: 00 db print, "!33*44=",0 2107: 0021002C 210B: 09C5 db byte, 33, byte, 44, mult, printdec 210D: 210D: 00DF002C 2111: 0903 vt18 db byte, -33, byte, 44, mult, number 2113: 54FA dw -33*44 2115: DD db eq 2116: 2D12 db bra_if,vt19-$ 2118: BF212D33 211C: 332A3434 2120: 3D00 db print, "!-33*44=",0 2122: 00DF002C 2126: 09C5 db byte, -33, byte, 44, mult, printdec 2128: 2128: 002100D4 212C: 0903 vt19 db byte, 33, byte, -44, mult, number 212E: 54FA dw -33*44 2130: DD db eq 2131: 2D12 db bra_if,vt20-$ 2133: BF213333 2137: 2A2D3434 213B: 3D00 db print, "!33*-44=",0 213D: 002100D4 2141: 09C5 db byte, 33, byte, -44, mult, printdec 2143: 2143: 0000002C 2147: 090000DD vt20 db byte, 0, byte, 44, mult, byte, 0, eq 214B: 2D10 db bra_if,vt21-$ 214D: BF21302A 2151: 34343D00 db print, "!0*44=",0 2155: 0000002C 2159: 09C5 db byte, 0, byte, 44, mult, printdec 215B: 215B: 00DF0000 215F: 090000DD vt21 db byte, -33, byte, 0, mult, byte, 0, eq 2163: 2D11 db bra_if,vt22-$ 2165: BF212D33 2169: 332A303D 216D: 00 db print, "!-33*0=",0 216E: 00DF0000 2172: 09C5 db byte, -33, byte, 0, mult, printdec 2174: 2174: 03 vt22 db number 2175: 4D01 dw 333 2177: 00D40903 db byte, -44, mult, number 217B: C4C6 dw 333*-44 217D: DD db eq 217E: 2D14 db bra_if,vt23-$ 2180: BF213333 2184: 332A2D34 2188: 343D00 db print, "!333*-44=",0 218B: 03 db number 218C: 4D01 dw 333 218E: 00D409C5 db byte, -44, mult, printdec 2192: 2192: 00DF00D4 2196: 0903 vt23 db byte, -33, byte, -44, mult, number 2198: AC05 dw 33*44 219A: DD db eq 219B: 2D13 db bra_if,vt25-$ 219D: BF212D33 21A1: 332A2D34 21A5: 343D00 db print, "!-33*-44=",0 21A8: 00DF00D4 21AC: 09C5 db byte, -33, byte, -44, mult, printdec 21AE: 21AE: 00050004 21B2: 920004DD vt25 db byte, 5, byte, 4, min, byte, 4, eq 21B6: 2D0D db bra_if,vt26-$ 21B8: BF216D69 21BC: 6E28352C 21C0: 342900 db print, "!min(5,4)",0 21C3: 21C3: 00FB00FC 21C7: 9200FBDD vt26 db byte, -5, byte, -4, min, byte, -5, eq 21CB: 2D0F db bra_if,vt27-$ 21CD: BF216D69 21D1: 6E282D35 21D5: 2C2D3429 21D9: 00 db print, "!min(-5,-4)",0 21DA: 21DA: 00FB0004 21DE: 9200FBDD vt27 db byte, -5, byte, 4, min, byte, -5, eq 21E2: 2D0E db bra_if,vt28-$ 21E4: BF216D69 21E8: 6E282D35 21EC: 2C342900 db print, "!min(-5,4)",0 21F0: 21F0: 000500FC 21F4: 9200FCDD vt28 db byte, 5, byte, -4, min, byte, -4, eq 21F8: 2D0E db bra_if,vt29-$ 21FA: BF216D69 21FE: 6E28352C 2202: 2D342900 db print, "!min(5,-4)",0 2206: 2206: vt29 2206: 2206: BF20646F 220A: 6E652E00 db print," done.",0 220E: 69 db to_real 220F: C9 ret 2210: 2210: 2210: 2210: 2210: 2210: 2210: 2210: 2210: #include "vip test.ass" 2210: 2210: 2210: sys_info_attr equ cyan_paper+black+bright 2210: sys_info_h_attr equ green_paper+white 2210: 2210: 2210: ; ---------------------------------------------- 2210: ; System-Info anzeigen 2210: ; 2210: ; Verzweigt danach wieder zum Hauptmenu 2210: ; 2210: ; in: -- 2210: ; out: does not return 2210: ; mod: does not return 2210: 2210: system_info: 2210: 2210: E7 rst vip 2211: 2211: ; "Software Info" 2211: 2211: BF066802 db print, ctl_setattr,sys_info_attr,ctl_cls 2215: 0627 db ctl_setattr,sys_info_h_attr 2217: 03012053 221B: 6F667477 221F: 61726520 2223: 496E666F db ctl_locate,1,32, "Software Info" 2227: 06680D db ctl_setattr,sys_info_attr,$0d 222A: 222A: ; "IC Tester Version" 222A: 222A: 0D494320 222E: 54657374 2232: 65722076 2236: 65727369 223A: 6F6E3A0A 223E: 302E31 db $0d,"IC Tester version:", ctl_tab, "0.1" 2241: 0D4C6173 2245: 74206D6F 2249: 64696669 224D: 65643A0A 2251: 0A342E4F 2255: 63742E32 2259: 303036 db $0d,"Last modified:", ctl_tab,ctl_tab, __date__ 225C: 225C: ; "Mem pack size" 225C: 225C: 0D4D656D 2260: 6F727920 2264: 7061636B 2268: 2073697A 226C: 653A0480 2270: 00 db $0d,"Memory pack size:", ctl_setcol,128,0 2271: 03 db number 2272: B903 dw mempack_end-mempack_start 2274: C5 db printdec 2275: 2275: ; "Scr pack size" 2275: 2275: BF0D5363 2279: 7265656E 227D: 20706163 2281: 6B207369 2285: 7A653A04 2289: 8000 db print, $0d,"Screen pack size:", ctl_setcol,128,$00 228B: 03 db number 228C: FE02 dw screen_end-screen_start 228E: C5 db printdec 228F: 228F: ; "Text pack size" 228F: 228F: BF0D5465 2293: 78742070 2297: 61636B20 229B: 73697A65 229F: 3A048000 db print, $0d,"Text pack size:", ctl_setcol,128,$00 22A3: 03 db number 22A4: B107 dw print_end-print_start 22A6: C5 db printdec 22A7: 22A7: ; "Virtual machine size" 22A7: 22A7: BF0D5669 22AB: 72747561 22AF: 6C206D61 22B3: 6368696E 22B7: 65207369 22BB: 7A653A04 22BF: 8000 db print, $0d,"Virtual machine size:", ctl_setcol, 128, 0 22C1: 03 db number 22C2: 8D04 dw vip_end-vip_start 22C4: C5 db printdec 22C5: BF202874 22C9: 61626C65 22CD: 3A2000 db print, " (table: ",0 22D0: 03 db number 22D1: F400 dw v_tab_end-v_tab 22D3: C5 db printdec 22D4: BF2900 db print, ")",0 22D7: 22D7: ; "Hardware Info" 22D7: 22D7: BF0D0D06 22DB: 27 db print, $0d,$0d,ctl_setattr,sys_info_h_attr 22DC: 04204861 22E0: 72647761 22E4: 72652049 22E8: 6E666F db ctl_setcol,32, "Hardware Info" 22EB: 06680D00 db ctl_setattr,sys_info_attr,$0d,0 22EF: 22EF: ; "Total Ram Size" 22EF: 22EF: BF0D546F 22F3: 74616C20 22F7: 52414D20 22FB: 73697A65 22FF: 3A048024 2303: 00 db print, $0d, "Total RAM size:", ctl_setcol,128,'$',0 2304: 03005B12 db number, RAMTOP%256, RAMTOP/256, peek 2308: 030040DB db number, $00, $40, sub 230C: 6BC8 db dup, printhex 230E: BF202800 db print, " (",0 2312: C5 db printdec 2313: BF2900 db print, ")",0 2316: 2316: ; "Ram Bytes Free" 2316: 2316: BF0D5241 231A: 4D206279 231E: 74657320 2322: 66726565 2326: 3A048000 db print, $0d,"RAM bytes free:", ctl_setcol,128,$00 232A: 36 db opcode 232B: 770E dw v_mem_get_free_total 232D: C5 db printdec 232E: 232E: ; "Rom Bytes Free" 232E: 232E: BF0D524F 2332: 4D206279 2336: 74657320 233A: 756E7573 233E: 65643A0A 2342: 00 db print, $0d,"ROM bytes unused:", ctl_tab,0 2343: 03004003 2347: 2026DB db number, $00, $40, number, code_end%256, code_end/256, sub 234A: C5 db printdec 234B: 234B: ; "Min. Stack Free" 234B: 234B: BF0D4D69 234F: 6E2E2073 2353: 7461636B 2357: 20667265 235B: 653A0480 235F: 00 db print, $0d,"Min. stack free:", ctl_setcol,128,0 2360: 36 db opcode 2361: 8123 dw v_calc_min_stack_free 2363: C5 db printdec 2364: 69 db to_real 2365: 2365: 2365: ; "Press Any Key" 2365: 2365: CD6B23 call press_any_key 2368: C3BE00 jp main_menu 236B: 236B: 236B: 236B: ; --------------------------------------------- 236B: ; Display "Press any key" 236B: ; and wait for key and flush key 236B: ; 236B: ; in: -- 236B: ; out: -- 236B: ; mod: af 236B: 236B: press_any_key: 236B: CF rst print_msg 236C: 0D0D0422 2370: 0617 defb $0d,$0d,ctl_setcol,34,ctl_setattr,red_paper+white 2372: 5B707265 2376: 7373206B 237A: 65795D00 defm "[press key]",$00 237E: C3CC19 jp wait_newkey 2381: 2381: 2381: 2381: 2381: ; --------------------------------------- 2381: ; Ermittle das bisher aufgetretene Stack-Free-Minimum 2381: ; Ann.: Der Stack schließt sich direkt an das dynamisch verwaltete freie RAM an. 2381: ; Jemals verwendete Bytes auf dem Stack werden an ihrem Wert != 0 erkannt. 2381: 2381: v_calc_min_stack_free ; opcode v_calc_min_stack_free -- 2381: D5 push de 2382: 2382: 2A235B ld hl,(mem_end) 2385: 545D ld de,hl 2387: AF xor a 2388: 2B dec hl 2389: 2389: 23 cms1 inc hl ; suche das erste byte != 0 238A: B6 or (hl) 238B: 28FC jr z,cms1 238D: 238D: ED52 sbc hl,de 238F: 238F: EB ex hl,de 2390: FDE9 jp (iy) 2392: 2392: 2392: 2392: #include "sysinfo.ass" 2392: 2392: print_obit_menu: 2392: CF rst print_msg 2393: 010510 db ctl_home,ctl_setrow,16 2396: 0668 db ctl_setattr,cyan_paper+black+bright 2398: 00 db 0 2399: 2399: 210050 ld hl,$5000 ; Zeile 16 239C: 011008 ld bc,256*8 + 16 ; rows, char_cols 239F: 3E68 ld a,cyan_paper+black+bright 23A1: CD9B0C call clear_cbox_with_attr 23A4: 23A4: CF rst print_msg 23A5: 28542904 23A9: 18546F67 23AD: 676C6520 23B1: 70696E db "(T)", ctl_setcol,24, "Toggle pin" 23B4: ;db $0d, "(F)", ctl_setcol,24, "Trigger pin" 23B4: 0D283129 23B8: 04185365 23BC: 74207069 23C0: 6E20746F 23C4: 20273127 db $0d, "(1)", ctl_setcol,24, "Set pin to '1'" 23C8: 0D283029 23CC: 04185365 23D0: 74207069 23D4: 6E20746F 23D8: 20273027 db $0d, "(0)", ctl_setcol,24, "Set pin to '0'" 23DC: 00 db 0 23DD: C9 ret 23DE: 23DE: print_type_menu: 23DE: CF rst print_msg 23DF: 010510 db ctl_home,ctl_setrow,16 23E2: 0668 db ctl_setattr,cyan_paper+black+bright 23E4: 00 db 0 23E5: 23E5: 210050 ld hl,$5000 ; Zeile 16 23E8: 011008 ld bc,256*8 + 16 ; rows, char_cols 23EB: 3E68 ld a,cyan_paper+black+bright 23ED: CD9B0C call clear_cbox_with_attr 23F0: 23F0: CF rst print_msg 23F1: 28492904 23F5: 18496E70 23F9: 7574 db "(I)", ctl_setcol,24, "Input" 23FB: 0D284F29 23FF: 04184F75 2403: 74707574 db $0d, "(O)", ctl_setcol,24, "Output" 2407: 0D283329 240B: 04183373 240F: 74617465 2413: 206F7574 2417: 707574 db $0d, "(3)", ctl_setcol,24, "3state output" 241A: 0D284B29 241E: 04186F2E 2422: 4B2E206F 2426: 75747075 242A: 74 db $0d, "(K)", ctl_setcol,24, "o.K. output" 242B: 0D285829 242F: 0418492F 2433: 4F db $0d, "(X)", ctl_setcol,24, "I/O" 2434: 0D284E29 2438: 04186E2E 243C: 632E db $0d, "(N)", ctl_setcol,24, "n.c." 243E: 0D285629 2442: 04185663 2446: 63 db $0d, "(V)", ctl_setcol,24, "Vcc" ; zufällig selbe Taste wie '+': Vcc on 2447: 0D284729 244B: 0418474E 244F: 44 db $0d, "(G)", ctl_setcol,24, "GND" ; zufällig selbe Taste wie '-': Vcc off 2450: ; db $0d, "(U)", ctl_setcol,24, "unknown" 2450: 00 db 0 2451: C9 ret 2452: 2452: print_name_menu: 2452: CF rst print_msg 2453: 010510 db ctl_home,ctl_setrow,16 2456: 0668 db ctl_setattr,cyan_paper+black+bright 2458: 00 db 0 2459: 2459: 210050 ld hl,$5000 ; Zeile 16 245C: 011008 ld bc,256*8 + 16 ; rows, char_cols 245F: 3E68 ld a,cyan_paper+black+bright 2461: CD9B0C call clear_cbox_with_attr 2464: 2464: CF rst print_msg 2465: 5B454E54 2469: 45525D20 246D: 746F2065 2471: 64697420 2475: 6E616D65 db "[ENTER] to edit name" 2479: 0D652E67 247D: 2E3A db $0d, "e.g.:" 247F: 0D202041 2483: 78782061 2487: 64647265 248B: 7373 db $0d, " Axx address" 248D: 0D202044 2491: 78782064 2495: 617461 db $0d, " Dxx data" 2498: 0D202056 249C: 63632073 24A0: 7570706C 24A4: 79 db $0d, " Vcc supply" 24A5: 0D202047 24A9: 4E442067 24AD: 726F756E 24B1: 64 db $0d, " GND ground" 24B2: 0D20202F 24B6: 43452C20 24BA: 2F57452C 24BE: 202F5244 db $0d, " /CE, /WE, /RD" 24C2: 00 db 0 24C3: C9 ret 24C4: 24C4: 24C4: free_test_menu: 24C4: CF rst print_msg 24C5: 066802 db ctl_setattr,cyan_paper+black+bright,ctl_cls 24C8: 0627 db ctl_setattr,green_paper+white 24CA: 0D204672 24CE: 65652054 24D2: 65737420 24D6: 0D db $0d, " Free Test ", $0d 24D7: 0668 db ctl_setattr,cyan_paper+black+bright 24D9: 24D9: 0D285129 24DD: 04184578 24E1: 6974 db $0d,"(Q)", ctl_setcol,24, "Exit" 24E3: 0D db $0d 24E4: 0D285A29 24E8: 04185365 24EC: 74207069 24F0: 6E20636F 24F4: 756E74 db $0d,"(Z)", ctl_setcol,24, "Set pin count" 24F7: 0D284529 24FB: 04184564 24FF: 69742049 2503: 4320696E 2507: 666F db $0d,"(E)", ctl_setcol,24, "Edit IC info" 2509: 0D285229 250D: 04184665 2511: 74636820 2515: 49432069 2519: 6E666F db $0d,"(R)", ctl_setcol,24, "Fetch IC info" 251C: 0D285729 2520: 04185374 2524: 6F726520 2528: 49432069 252C: 6E666F db $0d,"(W)", ctl_setcol,24, "Store IC info" 252F: 0D285029 2533: 04184361 2537: 6C632E20 253B: 63686563 253F: 6B73756D db $0d,"(P)", ctl_setcol,24, "Calc. checksum" 2543: 0D db $0d 2544: 0D282B29 2548: 04185377 254C: 69746368 2550: 20566363 2554: 204F4E db $0d,"(+)", ctl_setcol,24, "Switch Vcc ON" ; or 'J' 2557: 0D282D29 255B: 04185377 255F: 69746368 2563: 20566363 2567: 204F4646 db $0d,"(-)", ctl_setcol,24, "Switch Vcc OFF" ; or 'K' 256B: 0D9C9D db $0d, charcode_left_arrow,charcode_down_arrow 256E: 9E9F db charcode_up_arrow, charcode_right_arrow 2570: 206D6F76 2574: 65206172 2578: 6F756E64 db " move around" 257C: 00 db 0 257D: 257D: 257D: CD961C call start_pin_display 2580: CDC91A call ic_draw_all_pin_types 2583: ED4BA15C ld bc,(ic_hilight_row_col) ; b=row, c=col 2587: CDD11B call ic_set_hilight 258A: 258A: 258A: 258A: ED4BA15C ft1 ld bc,(ic_hilight_row_col) ; b=row, c=col 258E: CDA21B call test_col_c_is_obit ; z = ja 2591: CC9223 call z,print_obit_menu 2594: CDA91B call test_col_c_is_name ; z = ja 2597: CC5224 call z,print_name_menu 259A: CDB01B call test_col_c_is_type ; z = ja 259D: CCDE23 call z,print_type_menu 25A0: 25A0: ED7B005B ld sp,(RAMTOP) 25A4: CD5617 call print_error_message ; falls vorhanden 25A7: 25A7: CDA200 call inkey_dispatcher 25AA: 25AA: ; allways present keys: 25AA: 71 defb 'q' 25AB: BE00 defw main_menu 25AD: 7A defb 'z' 25AE: 1F26 defw set_pin_count 25B0: 65 defb 'e' 25B1: 1F26 defw edit_pin_info 25B3: 72 defb 'r' 25B4: 1F26 defw fetch_ic_info 25B6: 77 defb 'w' 25B7: 1F26 defw store_ic_info 25B9: 70 defb 'p' 25BA: 1F26 defw calc_checksum 25BC: 2B defb '+' 25BD: DA1D defw ic_switch_vcc_on 25BF: 4B defb 'K' ; selbe Taste nur mit caps shift 25C0: DA1D defw ic_switch_vcc_on 25C2: 2D defb '-' 25C3: E21D defw ic_switch_vcc_off 25C5: 4A defb 'J' ; selbe Taste nur mit caps shift 25C6: E21D defw ic_switch_vcc_off 25C8: 25C8: ; obit menu: 25C8: 74 defb 't' 25C9: 011D defw ic_toggle_current_pin 25CB: 66 defb 'f' 25CC: 0F1D defw ic_trigger_current_pin 25CE: 31 defb '1' 25CF: F31C defw ic_set_current_pin 25D1: 30 defb '0' 25D2: E11C defw ic_reset_current_pin 25D4: 25D4: ; type menu: 25D4: 69 defb 'i' 25D5: F725 defw set_pintype_input 25D7: 6F defb 'o' 25D8: FB25 defw set_pintype_output 25DA: 33 defb '3' 25DB: FF25 defw set_pintype_3state 25DD: 6B defb 'k' 25DE: 0326 defw set_pintype_oK 25E0: 78 defb 'x' 25E1: 0726 defw set_pintype_io 25E3: 6E defb 'n' 25E4: 0B26 defw set_pintype_nc 25E6: 76 defb 'v' 25E7: 0F26 defw set_pintype_vcc 25E9: 67 defb 'g' 25EA: 1326 defw set_pintype_gnd 25EC: 75 defb 'u' 25ED: 1726 defw set_pintype_unknown 25EF: 25EF: ; name menu: 25EF: 0D defb 13 25F0: 1F26 defw edit_pin_name 25F2: 25F2: 25F2: 00 defb 0 25F3: 541C defw ic_move_hilight ; handle cursor key or ignore invalid key 25F5: 25F5: 1893 jr ft1 25F7: 25F7: 25F7: 25F7: 25F7: 25F7: set_pintype_input 25F7: 3E03 ld a,ic_pin_type_input 25F9: 181E jr spt1 25FB: set_pintype_output 25FB: 3E04 ld a,ic_pin_type_output 25FD: 181A jr spt1 25FF: set_pintype_3state 25FF: 3E07 ld a,ic_pin_type_3state 2601: 1816 jr spt1 2603: set_pintype_oK 2603: 3E06 ld a,ic_pin_type_oK 2605: 1812 jr spt1 2607: set_pintype_io 2607: 3E05 ld a,ic_pin_type_io 2609: 180E jr spt1 260B: set_pintype_nc 260B: 3E08 ld a,ic_pin_type_nc 260D: 180A jr spt1 260F: set_pintype_vcc 260F: 3E02 ld a,ic_pin_type_vcc 2611: 1806 jr spt1 2613: set_pintype_gnd 2613: 3E01 ld a,ic_pin_type_gnd 2615: 1802 jr spt1 2617: set_pintype_unknown 2617: 3E00 ld a,ic_pin_type_unknown 2619: ;jr spt1 2619: CDBD1A spt1 call ic_set_pin_type_for_current_pin 261C: C3521C jp ic_move_hilight_down 261F: 261F: edit_pin_name 261F: set_pin_count 261F: edit_pin_info 261F: fetch_ic_info 261F: store_ic_info 261F: calc_checksum 261F: 261F: C9 ret ; NIMP 2620: 2620: #include "free test.ass" 2620: 2620: 2620: 2620: 2620: FFFFFFFF 2624: FFFFFFFF 2628: FFFFFFFF 262C: FFFFFFFF 2630: FFFFFFFF 2634: FFFFFFFF 2638: FFFFFFFF 263C: FFFFFFFF 2640: FFFFFFFF 2644: FFFFFFFF 2648: FFFFFFFF 264C: FFFFFFFF 2650: FFFFFFFF 2654: FFFFFFFF 2658: FFFFFFFF 265C: FFFFFFFF 2660: FFFFFFFF 2664: FFFFFFFF 2668: FFFFFFFF 266C: FFFFFFFF 2670: FFFFFFFF 2674: FFFFFFFF 2678: FFFFFFFF 267C: FFFFFFFF 2680: FFFFFFFF 2684: FFFFFFFF 2688: FFFFFFFF 268C: FFFFFFFF 2690: FFFFFFFF 2694: FFFFFFFF 2698: FFFFFFFF 269C: FFFFFFFF 26A0: FFFFFFFF 26A4: FFFFFFFF 26A8: FFFFFFFF 26AC: FFFFFFFF 26B0: FFFFFFFF 26B4: FFFFFFFF 26B8: FFFFFFFF 26BC: FFFFFFFF 26C0: FFFFFFFF 26C4: FFFFFFFF 26C8: FFFFFFFF 26CC: FFFFFFFF 26D0: FFFFFFFF 26D4: FFFFFFFF 26D8: FFFFFFFF 26DC: FFFFFFFF 26E0: FFFFFFFF 26E4: FFFFFFFF 26E8: FFFFFFFF 26EC: FFFFFFFF 26F0: FFFFFFFF 26F4: FFFFFFFF 26F8: FFFFFFFF 26FC: FFFFFFFF 2700: FFFFFFFF 2704: FFFFFFFF 2708: FFFFFFFF 270C: FFFFFFFF 2710: FFFFFFFF 2714: FFFFFFFF 2718: FFFFFFFF 271C: FFFFFFFF 2720: FFFFFFFF 2724: FFFFFFFF 2728: FFFFFFFF 272C: FFFFFFFF 2730: FFFFFFFF 2734: FFFFFFFF 2738: FFFFFFFF 273C: FFFFFFFF 2740: FFFFFFFF 2744: FFFFFFFF 2748: FFFFFFFF 274C: FFFFFFFF 2750: FFFFFFFF 2754: FFFFFFFF 2758: FFFFFFFF 275C: FFFFFFFF 2760: FFFFFFFF 2764: FFFFFFFF 2768: FFFFFFFF 276C: FFFFFFFF 2770: FFFFFFFF 2774: FFFFFFFF 2778: FFFFFFFF 277C: FFFFFFFF 2780: FFFFFFFF 2784: FFFFFFFF 2788: FFFFFFFF 278C: FFFFFFFF 2790: FFFFFFFF 2794: FFFFFFFF 2798: FFFFFFFF 279C: FFFFFFFF 27A0: FFFFFFFF 27A4: FFFFFFFF 27A8: FFFFFFFF 27AC: FFFFFFFF 27B0: FFFFFFFF 27B4: FFFFFFFF 27B8: FFFFFFFF 27BC: FFFFFFFF 27C0: FFFFFFFF 27C4: FFFFFFFF 27C8: FFFFFFFF 27CC: FFFFFFFF 27D0: FFFFFFFF 27D4: FFFFFFFF 27D8: FFFFFFFF 27DC: FFFFFFFF 27E0: FFFFFFFF 27E4: FFFFFFFF 27E8: FFFFFFFF 27EC: FFFFFFFF 27F0: FFFFFFFF 27F4: FFFFFFFF 27F8: FFFFFFFF 27FC: FFFFFFFF 2800: FFFFFFFF 2804: FFFFFFFF 2808: FFFFFFFF 280C: FFFFFFFF 2810: FFFFFFFF 2814: FFFFFFFF 2818: FFFFFFFF 281C: FFFFFFFF 2820: FFFFFFFF 2824: FFFFFFFF 2828: FFFFFFFF 282C: FFFFFFFF 2830: FFFFFFFF 2834: FFFFFFFF 2838: FFFFFFFF 283C: FFFFFFFF 2840: FFFFFFFF 2844: FFFFFFFF 2848: FFFFFFFF 284C: FFFFFFFF 2850: FFFFFFFF 2854: FFFFFFFF 2858: FFFFFFFF 285C: FFFFFFFF 2860: FFFFFFFF 2864: FFFFFFFF 2868: FFFFFFFF 286C: FFFFFFFF 2870: FFFFFFFF 2874: FFFFFFFF 2878: FFFFFFFF 287C: FFFFFFFF 2880: FFFFFFFF 2884: FFFFFFFF 2888: FFFFFFFF 288C: FFFFFFFF 2890: FFFFFFFF 2894: FFFFFFFF 2898: FFFFFFFF 289C: FFFFFFFF 28A0: FFFFFFFF 28A4: FFFFFFFF 28A8: FFFFFFFF 28AC: FFFFFFFF 28B0: FFFFFFFF 28B4: FFFFFFFF 28B8: FFFFFFFF 28BC: FFFFFFFF 28C0: FFFFFFFF 28C4: FFFFFFFF 28C8: FFFFFFFF 28CC: FFFFFFFF 28D0: FFFFFFFF 28D4: FFFFFFFF 28D8: FFFFFFFF 28DC: FFFFFFFF 28E0: FFFFFFFF 28E4: FFFFFFFF 28E8: FFFFFFFF 28EC: FFFFFFFF 28F0: FFFFFFFF 28F4: FFFFFFFF 28F8: FFFFFFFF 28FC: FFFFFFFF 2900: FFFFFFFF 2904: FFFFFFFF 2908: FFFFFFFF 290C: FFFFFFFF 2910: FFFFFFFF 2914: FFFFFFFF 2918: FFFFFFFF 291C: FFFFFFFF 2920: FFFFFFFF 2924: FFFFFFFF 2928: FFFFFFFF 292C: FFFFFFFF 2930: FFFFFFFF 2934: FFFFFFFF 2938: FFFFFFFF 293C: FFFFFFFF 2940: FFFFFFFF 2944: FFFFFFFF 2948: FFFFFFFF 294C: FFFFFFFF 2950: FFFFFFFF 2954: FFFFFFFF 2958: FFFFFFFF 295C: FFFFFFFF 2960: FFFFFFFF 2964: FFFFFFFF 2968: FFFFFFFF 296C: FFFFFFFF 2970: FFFFFFFF 2974: FFFFFFFF 2978: FFFFFFFF 297C: FFFFFFFF 2980: FFFFFFFF 2984: FFFFFFFF 2988: FFFFFFFF 298C: FFFFFFFF 2990: FFFFFFFF 2994: FFFFFFFF 2998: FFFFFFFF 299C: FFFFFFFF 29A0: FFFFFFFF 29A4: FFFFFFFF 29A8: FFFFFFFF 29AC: FFFFFFFF 29B0: FFFFFFFF 29B4: FFFFFFFF 29B8: FFFFFFFF 29BC: FFFFFFFF 29C0: FFFFFFFF 29C4: FFFFFFFF 29C8: FFFFFFFF 29CC: FFFFFFFF 29D0: FFFFFFFF 29D4: FFFFFFFF 29D8: FFFFFFFF 29DC: FFFFFFFF 29E0: FFFFFFFF 29E4: FFFFFFFF 29E8: FFFFFFFF 29EC: FFFFFFFF 29F0: FFFFFFFF 29F4: FFFFFFFF 29F8: FFFFFFFF 29FC: FFFFFFFF 2A00: FFFFFFFF 2A04: FFFFFFFF 2A08: FFFFFFFF 2A0C: FFFFFFFF 2A10: FFFFFFFF 2A14: FFFFFFFF 2A18: FFFFFFFF 2A1C: FFFFFFFF 2A20: FFFFFFFF 2A24: FFFFFFFF 2A28: FFFFFFFF 2A2C: FFFFFFFF 2A30: FFFFFFFF 2A34: FFFFFFFF 2A38: FFFFFFFF 2A3C: FFFFFFFF 2A40: FFFFFFFF 2A44: FFFFFFFF 2A48: FFFFFFFF 2A4C: FFFFFFFF 2A50: FFFFFFFF 2A54: FFFFFFFF 2A58: FFFFFFFF 2A5C: FFFFFFFF 2A60: FFFFFFFF 2A64: FFFFFFFF 2A68: FFFFFFFF 2A6C: FFFFFFFF 2A70: FFFFFFFF 2A74: FFFFFFFF 2A78: FFFFFFFF 2A7C: FFFFFFFF 2A80: FFFFFFFF 2A84: FFFFFFFF 2A88: FFFFFFFF 2A8C: FFFFFFFF 2A90: FFFFFFFF 2A94: FFFFFFFF 2A98: FFFFFFFF 2A9C: FFFFFFFF 2AA0: FFFFFFFF 2AA4: FFFFFFFF 2AA8: FFFFFFFF 2AAC: FFFFFFFF 2AB0: FFFFFFFF 2AB4: FFFFFFFF 2AB8: FFFFFFFF 2ABC: FFFFFFFF 2AC0: FFFFFFFF 2AC4: FFFFFFFF 2AC8: FFFFFFFF 2ACC: FFFFFFFF 2AD0: FFFFFFFF 2AD4: FFFFFFFF 2AD8: FFFFFFFF 2ADC: FFFFFFFF 2AE0: FFFFFFFF 2AE4: FFFFFFFF 2AE8: FFFFFFFF 2AEC: FFFFFFFF 2AF0: FFFFFFFF 2AF4: FFFFFFFF 2AF8: FFFFFFFF 2AFC: FFFFFFFF 2B00: FFFFFFFF 2B04: FFFFFFFF 2B08: FFFFFFFF 2B0C: FFFFFFFF 2B10: FFFFFFFF 2B14: FFFFFFFF 2B18: FFFFFFFF 2B1C: FFFFFFFF 2B20: FFFFFFFF 2B24: FFFFFFFF 2B28: FFFFFFFF 2B2C: FFFFFFFF 2B30: FFFFFFFF 2B34: FFFFFFFF 2B38: FFFFFFFF 2B3C: FFFFFFFF 2B40: FFFFFFFF 2B44: FFFFFFFF 2B48: FFFFFFFF 2B4C: FFFFFFFF 2B50: FFFFFFFF 2B54: FFFFFFFF 2B58: FFFFFFFF 2B5C: FFFFFFFF 2B60: FFFFFFFF 2B64: FFFFFFFF 2B68: FFFFFFFF 2B6C: FFFFFFFF 2B70: FFFFFFFF 2B74: FFFFFFFF 2B78: FFFFFFFF 2B7C: FFFFFFFF 2B80: FFFFFFFF 2B84: FFFFFFFF 2B88: FFFFFFFF 2B8C: FFFFFFFF 2B90: FFFFFFFF 2B94: FFFFFFFF 2B98: FFFFFFFF 2B9C: FFFFFFFF 2BA0: FFFFFFFF 2BA4: FFFFFFFF 2BA8: FFFFFFFF 2BAC: FFFFFFFF 2BB0: FFFFFFFF 2BB4: FFFFFFFF 2BB8: FFFFFFFF 2BBC: FFFFFFFF 2BC0: FFFFFFFF 2BC4: FFFFFFFF 2BC8: FFFFFFFF 2BCC: FFFFFFFF 2BD0: FFFFFFFF 2BD4: FFFFFFFF 2BD8: FFFFFFFF 2BDC: FFFFFFFF 2BE0: FFFFFFFF 2BE4: FFFFFFFF 2BE8: FFFFFFFF 2BEC: FFFFFFFF 2BF0: FFFFFFFF 2BF4: FFFFFFFF 2BF8: FFFFFFFF 2BFC: FFFFFFFF 2C00: FFFFFFFF 2C04: FFFFFFFF 2C08: FFFFFFFF 2C0C: FFFFFFFF 2C10: FFFFFFFF 2C14: FFFFFFFF 2C18: FFFFFFFF 2C1C: FFFFFFFF 2C20: FFFFFFFF 2C24: FFFFFFFF 2C28: FFFFFFFF 2C2C: FFFFFFFF 2C30: FFFFFFFF 2C34: FFFFFFFF 2C38: FFFFFFFF 2C3C: FFFFFFFF 2C40: FFFFFFFF 2C44: FFFFFFFF 2C48: FFFFFFFF 2C4C: FFFFFFFF 2C50: FFFFFFFF 2C54: FFFFFFFF 2C58: FFFFFFFF 2C5C: FFFFFFFF 2C60: FFFFFFFF 2C64: FFFFFFFF 2C68: FFFFFFFF 2C6C: FFFFFFFF 2C70: FFFFFFFF 2C74: FFFFFFFF 2C78: FFFFFFFF 2C7C: FFFFFFFF 2C80: FFFFFFFF 2C84: FFFFFFFF 2C88: FFFFFFFF 2C8C: FFFFFFFF 2C90: FFFFFFFF 2C94: FFFFFFFF 2C98: FFFFFFFF 2C9C: FFFFFFFF 2CA0: FFFFFFFF 2CA4: FFFFFFFF 2CA8: FFFFFFFF 2CAC: FFFFFFFF 2CB0: FFFFFFFF 2CB4: FFFFFFFF 2CB8: FFFFFFFF 2CBC: FFFFFFFF 2CC0: FFFFFFFF 2CC4: FFFFFFFF 2CC8: FFFFFFFF 2CCC: FFFFFFFF 2CD0: FFFFFFFF 2CD4: FFFFFFFF 2CD8: FFFFFFFF 2CDC: FFFFFFFF 2CE0: FFFFFFFF 2CE4: FFFFFFFF 2CE8: FFFFFFFF 2CEC: FFFFFFFF 2CF0: FFFFFFFF 2CF4: FFFFFFFF 2CF8: FFFFFFFF 2CFC: FFFFFFFF 2D00: FFFFFFFF 2D04: FFFFFFFF 2D08: FFFFFFFF 2D0C: FFFFFFFF 2D10: FFFFFFFF 2D14: FFFFFFFF 2D18: FFFFFFFF 2D1C: FFFFFFFF 2D20: FFFFFFFF 2D24: FFFFFFFF 2D28: FFFFFFFF 2D2C: FFFFFFFF 2D30: FFFFFFFF 2D34: FFFFFFFF 2D38: FFFFFFFF 2D3C: FFFFFFFF 2D40: FFFFFFFF 2D44: FFFFFFFF 2D48: FFFFFFFF 2D4C: FFFFFFFF 2D50: FFFFFFFF 2D54: FFFFFFFF 2D58: FFFFFFFF 2D5C: FFFFFFFF 2D60: FFFFFFFF 2D64: FFFFFFFF 2D68: FFFFFFFF 2D6C: FFFFFFFF 2D70: FFFFFFFF 2D74: FFFFFFFF 2D78: FFFFFFFF 2D7C: FFFFFFFF 2D80: FFFFFFFF 2D84: FFFFFFFF 2D88: FFFFFFFF 2D8C: FFFFFFFF 2D90: FFFFFFFF 2D94: FFFFFFFF 2D98: FFFFFFFF 2D9C: FFFFFFFF 2DA0: FFFFFFFF 2DA4: FFFFFFFF 2DA8: FFFFFFFF 2DAC: FFFFFFFF 2DB0: FFFFFFFF 2DB4: FFFFFFFF 2DB8: FFFFFFFF 2DBC: FFFFFFFF 2DC0: FFFFFFFF 2DC4: FFFFFFFF 2DC8: FFFFFFFF 2DCC: FFFFFFFF 2DD0: FFFFFFFF 2DD4: FFFFFFFF 2DD8: FFFFFFFF 2DDC: FFFFFFFF 2DE0: FFFFFFFF 2DE4: FFFFFFFF 2DE8: FFFFFFFF 2DEC: FFFFFFFF 2DF0: FFFFFFFF 2DF4: FFFFFFFF 2DF8: FFFFFFFF 2DFC: FFFFFFFF 2E00: FFFFFFFF 2E04: FFFFFFFF 2E08: FFFFFFFF 2E0C: FFFFFFFF 2E10: FFFFFFFF 2E14: FFFFFFFF 2E18: FFFFFFFF 2E1C: FFFFFFFF 2E20: FFFFFFFF 2E24: FFFFFFFF 2E28: FFFFFFFF 2E2C: FFFFFFFF 2E30: FFFFFFFF 2E34: FFFFFFFF 2E38: FFFFFFFF 2E3C: FFFFFFFF 2E40: FFFFFFFF 2E44: FFFFFFFF 2E48: FFFFFFFF 2E4C: FFFFFFFF 2E50: FFFFFFFF 2E54: FFFFFFFF 2E58: FFFFFFFF 2E5C: FFFFFFFF 2E60: FFFFFFFF 2E64: FFFFFFFF 2E68: FFFFFFFF 2E6C: FFFFFFFF 2E70: FFFFFFFF 2E74: FFFFFFFF 2E78: FFFFFFFF 2E7C: FFFFFFFF 2E80: FFFFFFFF 2E84: FFFFFFFF 2E88: FFFFFFFF 2E8C: FFFFFFFF 2E90: FFFFFFFF 2E94: FFFFFFFF 2E98: FFFFFFFF 2E9C: FFFFFFFF 2EA0: FFFFFFFF 2EA4: FFFFFFFF 2EA8: FFFFFFFF 2EAC: FFFFFFFF 2EB0: FFFFFFFF 2EB4: FFFFFFFF 2EB8: FFFFFFFF 2EBC: FFFFFFFF 2EC0: FFFFFFFF 2EC4: FFFFFFFF 2EC8: FFFFFFFF 2ECC: FFFFFFFF 2ED0: FFFFFFFF 2ED4: FFFFFFFF 2ED8: FFFFFFFF 2EDC: FFFFFFFF 2EE0: FFFFFFFF 2EE4: FFFFFFFF 2EE8: FFFFFFFF 2EEC: FFFFFFFF 2EF0: FFFFFFFF 2EF4: FFFFFFFF 2EF8: FFFFFFFF 2EFC: FFFFFFFF 2F00: FFFFFFFF 2F04: FFFFFFFF 2F08: FFFFFFFF 2F0C: FFFFFFFF 2F10: FFFFFFFF 2F14: FFFFFFFF 2F18: FFFFFFFF 2F1C: FFFFFFFF 2F20: FFFFFFFF 2F24: FFFFFFFF 2F28: FFFFFFFF 2F2C: FFFFFFFF 2F30: FFFFFFFF 2F34: FFFFFFFF 2F38: FFFFFFFF 2F3C: FFFFFFFF 2F40: FFFFFFFF 2F44: FFFFFFFF 2F48: FFFFFFFF 2F4C: FFFFFFFF 2F50: FFFFFFFF 2F54: FFFFFFFF 2F58: FFFFFFFF 2F5C: FFFFFFFF 2F60: FFFFFFFF 2F64: FFFFFFFF 2F68: FFFFFFFF 2F6C: FFFFFFFF 2F70: FFFFFFFF 2F74: FFFFFFFF 2F78: FFFFFFFF 2F7C: FFFFFFFF 2F80: FFFFFFFF 2F84: FFFFFFFF 2F88: FFFFFFFF 2F8C: FFFFFFFF 2F90: FFFFFFFF 2F94: FFFFFFFF 2F98: FFFFFFFF 2F9C: FFFFFFFF 2FA0: FFFFFFFF 2FA4: FFFFFFFF 2FA8: FFFFFFFF 2FAC: FFFFFFFF 2FB0: FFFFFFFF 2FB4: FFFFFFFF 2FB8: FFFFFFFF 2FBC: FFFFFFFF 2FC0: FFFFFFFF 2FC4: FFFFFFFF 2FC8: FFFFFFFF 2FCC: FFFFFFFF 2FD0: FFFFFFFF 2FD4: FFFFFFFF 2FD8: FFFFFFFF 2FDC: FFFFFFFF 2FE0: FFFFFFFF 2FE4: FFFFFFFF 2FE8: FFFFFFFF 2FEC: FFFFFFFF 2FF0: FFFFFFFF 2FF4: FFFFFFFF 2FF8: FFFFFFFF 2FFC: FFFFFFFF 3000: FFFFFFFF 3004: FFFFFFFF 3008: FFFFFFFF 300C: FFFFFFFF 3010: FFFFFFFF 3014: FFFFFFFF 3018: FFFFFFFF 301C: FFFFFFFF 3020: FFFFFFFF 3024: FFFFFFFF 3028: FFFFFFFF 302C: FFFFFFFF 3030: FFFFFFFF 3034: FFFFFFFF 3038: FFFFFFFF 303C: FFFFFFFF 3040: FFFFFFFF 3044: FFFFFFFF 3048: FFFFFFFF 304C: FFFFFFFF 3050: FFFFFFFF 3054: FFFFFFFF 3058: FFFFFFFF 305C: FFFFFFFF 3060: FFFFFFFF 3064: FFFFFFFF 3068: FFFFFFFF 306C: FFFFFFFF 3070: FFFFFFFF 3074: FFFFFFFF 3078: FFFFFFFF 307C: FFFFFFFF 3080: FFFFFFFF 3084: FFFFFFFF 3088: FFFFFFFF 308C: FFFFFFFF 3090: FFFFFFFF 3094: FFFFFFFF 3098: FFFFFFFF 309C: FFFFFFFF 30A0: FFFFFFFF 30A4: FFFFFFFF 30A8: FFFFFFFF 30AC: FFFFFFFF 30B0: FFFFFFFF 30B4: FFFFFFFF 30B8: FFFFFFFF 30BC: FFFFFFFF 30C0: FFFFFFFF 30C4: FFFFFFFF 30C8: FFFFFFFF 30CC: FFFFFFFF 30D0: FFFFFFFF 30D4: FFFFFFFF 30D8: FFFFFFFF 30DC: FFFFFFFF 30E0: FFFFFFFF 30E4: FFFFFFFF 30E8: FFFFFFFF 30EC: FFFFFFFF 30F0: FFFFFFFF 30F4: FFFFFFFF 30F8: FFFFFFFF 30FC: FFFFFFFF 3100: FFFFFFFF 3104: FFFFFFFF 3108: FFFFFFFF 310C: FFFFFFFF 3110: FFFFFFFF 3114: FFFFFFFF 3118: FFFFFFFF 311C: FFFFFFFF 3120: FFFFFFFF 3124: FFFFFFFF 3128: FFFFFFFF 312C: FFFFFFFF 3130: FFFFFFFF 3134: FFFFFFFF 3138: FFFFFFFF 313C: FFFFFFFF 3140: FFFFFFFF 3144: FFFFFFFF 3148: FFFFFFFF 314C: FFFFFFFF 3150: FFFFFFFF 3154: FFFFFFFF 3158: FFFFFFFF 315C: FFFFFFFF 3160: FFFFFFFF 3164: FFFFFFFF 3168: FFFFFFFF 316C: FFFFFFFF 3170: FFFFFFFF 3174: FFFFFFFF 3178: FFFFFFFF 317C: FFFFFFFF 3180: FFFFFFFF 3184: FFFFFFFF 3188: FFFFFFFF 318C: FFFFFFFF 3190: FFFFFFFF 3194: FFFFFFFF 3198: FFFFFFFF 319C: FFFFFFFF 31A0: FFFFFFFF 31A4: FFFFFFFF 31A8: FFFFFFFF 31AC: FFFFFFFF 31B0: FFFFFFFF 31B4: FFFFFFFF 31B8: FFFFFFFF 31BC: FFFFFFFF 31C0: FFFFFFFF 31C4: FFFFFFFF 31C8: FFFFFFFF 31CC: FFFFFFFF 31D0: FFFFFFFF 31D4: FFFFFFFF 31D8: FFFFFFFF 31DC: FFFFFFFF 31E0: FFFFFFFF 31E4: FFFFFFFF 31E8: FFFFFFFF 31EC: FFFFFFFF 31F0: FFFFFFFF 31F4: FFFFFFFF 31F8: FFFFFFFF 31FC: FFFFFFFF 3200: FFFFFFFF 3204: FFFFFFFF 3208: FFFFFFFF 320C: FFFFFFFF 3210: FFFFFFFF 3214: FFFFFFFF 3218: FFFFFFFF 321C: FFFFFFFF 3220: FFFFFFFF 3224: FFFFFFFF 3228: FFFFFFFF 322C: FFFFFFFF 3230: FFFFFFFF 3234: FFFFFFFF 3238: FFFFFFFF 323C: FFFFFFFF 3240: FFFFFFFF 3244: FFFFFFFF 3248: FFFFFFFF 324C: FFFFFFFF 3250: FFFFFFFF 3254: FFFFFFFF 3258: FFFFFFFF 325C: FFFFFFFF 3260: FFFFFFFF 3264: FFFFFFFF 3268: FFFFFFFF 326C: FFFFFFFF 3270: FFFFFFFF 3274: FFFFFFFF 3278: FFFFFFFF 327C: FFFFFFFF 3280: FFFFFFFF 3284: FFFFFFFF 3288: FFFFFFFF 328C: FFFFFFFF 3290: FFFFFFFF 3294: FFFFFFFF 3298: FFFFFFFF 329C: FFFFFFFF 32A0: FFFFFFFF 32A4: FFFFFFFF 32A8: FFFFFFFF 32AC: FFFFFFFF 32B0: FFFFFFFF 32B4: FFFFFFFF 32B8: FFFFFFFF 32BC: FFFFFFFF 32C0: FFFFFFFF 32C4: FFFFFFFF 32C8: FFFFFFFF 32CC: FFFFFFFF 32D0: FFFFFFFF 32D4: FFFFFFFF 32D8: FFFFFFFF 32DC: FFFFFFFF 32E0: FFFFFFFF 32E4: FFFFFFFF 32E8: FFFFFFFF 32EC: FFFFFFFF 32F0: FFFFFFFF 32F4: FFFFFFFF 32F8: FFFFFFFF 32FC: FFFFFFFF 3300: FFFFFFFF 3304: FFFFFFFF 3308: FFFFFFFF 330C: FFFFFFFF 3310: FFFFFFFF 3314: FFFFFFFF 3318: FFFFFFFF 331C: FFFFFFFF 3320: FFFFFFFF 3324: FFFFFFFF 3328: FFFFFFFF 332C: FFFFFFFF 3330: FFFFFFFF 3334: FFFFFFFF 3338: FFFFFFFF 333C: FFFFFFFF 3340: FFFFFFFF 3344: FFFFFFFF 3348: FFFFFFFF 334C: FFFFFFFF 3350: FFFFFFFF 3354: FFFFFFFF 3358: FFFFFFFF 335C: FFFFFFFF 3360: FFFFFFFF 3364: FFFFFFFF 3368: FFFFFFFF 336C: FFFFFFFF 3370: FFFFFFFF 3374: FFFFFFFF 3378: FFFFFFFF 337C: FFFFFFFF 3380: FFFFFFFF 3384: FFFFFFFF 3388: FFFFFFFF 338C: FFFFFFFF 3390: FFFFFFFF 3394: FFFFFFFF 3398: FFFFFFFF 339C: FFFFFFFF 33A0: FFFFFFFF 33A4: FFFFFFFF 33A8: FFFFFFFF 33AC: FFFFFFFF 33B0: FFFFFFFF 33B4: FFFFFFFF 33B8: FFFFFFFF 33BC: FFFFFFFF 33C0: FFFFFFFF 33C4: FFFFFFFF 33C8: FFFFFFFF 33CC: FFFFFFFF 33D0: FFFFFFFF 33D4: FFFFFFFF 33D8: FFFFFFFF 33DC: FFFFFFFF 33E0: FFFFFFFF 33E4: FFFFFFFF 33E8: FFFFFFFF 33EC: FFFFFFFF 33F0: FFFFFFFF 33F4: FFFFFFFF 33F8: FFFFFFFF 33FC: FFFFFFFF 3400: FFFFFFFF 3404: FFFFFFFF 3408: FFFFFFFF 340C: FFFFFFFF 3410: FFFFFFFF 3414: FFFFFFFF 3418: FFFFFFFF 341C: FFFFFFFF 3420: FFFFFFFF 3424: FFFFFFFF 3428: FFFFFFFF 342C: FFFFFFFF 3430: FFFFFFFF 3434: FFFFFFFF 3438: FFFFFFFF 343C: FFFFFFFF 3440: FFFFFFFF 3444: FFFFFFFF 3448: FFFFFFFF 344C: FFFFFFFF 3450: FFFFFFFF 3454: FFFFFFFF 3458: FFFFFFFF 345C: FFFFFFFF 3460: FFFFFFFF 3464: FFFFFFFF 3468: FFFFFFFF 346C: FFFFFFFF 3470: FFFFFFFF 3474: FFFFFFFF 3478: FFFFFFFF 347C: FFFFFFFF 3480: FFFFFFFF 3484: FFFFFFFF 3488: FFFFFFFF 348C: FFFFFFFF 3490: FFFFFFFF 3494: FFFFFFFF 3498: FFFFFFFF 349C: FFFFFFFF 34A0: FFFFFFFF 34A4: FFFFFFFF 34A8: FFFFFFFF 34AC: FFFFFFFF 34B0: FFFFFFFF 34B4: FFFFFFFF 34B8: FFFFFFFF 34BC: FFFFFFFF 34C0: FFFFFFFF 34C4: FFFFFFFF 34C8: FFFFFFFF 34CC: FFFFFFFF 34D0: FFFFFFFF 34D4: FFFFFFFF 34D8: FFFFFFFF 34DC: FFFFFFFF 34E0: FFFFFFFF 34E4: FFFFFFFF 34E8: FFFFFFFF 34EC: FFFFFFFF 34F0: FFFFFFFF 34F4: FFFFFFFF 34F8: FFFFFFFF 34FC: FFFFFFFF 3500: FFFFFFFF 3504: FFFFFFFF 3508: FFFFFFFF 350C: FFFFFFFF 3510: FFFFFFFF 3514: FFFFFFFF 3518: FFFFFFFF 351C: FFFFFFFF 3520: FFFFFFFF 3524: FFFFFFFF 3528: FFFFFFFF 352C: FFFFFFFF 3530: FFFFFFFF 3534: FFFFFFFF 3538: FFFFFFFF 353C: FFFFFFFF 3540: FFFFFFFF 3544: FFFFFFFF 3548: FFFFFFFF 354C: FFFFFFFF 3550: FFFFFFFF 3554: FFFFFFFF 3558: FFFFFFFF 355C: FFFFFFFF 3560: FFFFFFFF 3564: FFFFFFFF 3568: FFFFFFFF 356C: FFFFFFFF 3570: FFFFFFFF 3574: FFFFFFFF 3578: FFFFFFFF 357C: FFFFFFFF 3580: FFFFFFFF 3584: FFFFFFFF 3588: FFFFFFFF 358C: FFFFFFFF 3590: FFFFFFFF 3594: FFFFFFFF 3598: FFFFFFFF 359C: FFFFFFFF 35A0: FFFFFFFF 35A4: FFFFFFFF 35A8: FFFFFFFF 35AC: FFFFFFFF 35B0: FFFFFFFF 35B4: FFFFFFFF 35B8: FFFFFFFF 35BC: FFFFFFFF 35C0: FFFFFFFF 35C4: FFFFFFFF 35C8: FFFFFFFF 35CC: FFFFFFFF 35D0: FFFFFFFF 35D4: FFFFFFFF 35D8: FFFFFFFF 35DC: FFFFFFFF 35E0: FFFFFFFF 35E4: FFFFFFFF 35E8: FFFFFFFF 35EC: FFFFFFFF 35F0: FFFFFFFF 35F4: FFFFFFFF 35F8: FFFFFFFF 35FC: FFFFFFFF 3600: FFFFFFFF 3604: FFFFFFFF 3608: FFFFFFFF 360C: FFFFFFFF 3610: FFFFFFFF 3614: FFFFFFFF 3618: FFFFFFFF 361C: FFFFFFFF 3620: FFFFFFFF 3624: FFFFFFFF 3628: FFFFFFFF 362C: FFFFFFFF 3630: FFFFFFFF 3634: FFFFFFFF 3638: FFFFFFFF 363C: FFFFFFFF 3640: FFFFFFFF 3644: FFFFFFFF 3648: FFFFFFFF 364C: FFFFFFFF 3650: FFFFFFFF 3654: FFFFFFFF 3658: FFFFFFFF 365C: FFFFFFFF 3660: FFFFFFFF 3664: FFFFFFFF 3668: FFFFFFFF 366C: FFFFFFFF 3670: FFFFFFFF 3674: FFFFFFFF 3678: FFFFFFFF 367C: FFFFFFFF 3680: FFFFFFFF 3684: FFFFFFFF 3688: FFFFFFFF 368C: FFFFFFFF 3690: FFFFFFFF 3694: FFFFFFFF 3698: FFFFFFFF 369C: FFFFFFFF 36A0: FFFFFFFF 36A4: FFFFFFFF 36A8: FFFFFFFF 36AC: FFFFFFFF 36B0: FFFFFFFF 36B4: FFFFFFFF 36B8: FFFFFFFF 36BC: FFFFFFFF 36C0: FFFFFFFF 36C4: FFFFFFFF 36C8: FFFFFFFF 36CC: FFFFFFFF 36D0: FFFFFFFF 36D4: FFFFFFFF 36D8: FFFFFFFF 36DC: FFFFFFFF 36E0: FFFFFFFF 36E4: FFFFFFFF 36E8: FFFFFFFF 36EC: FFFFFFFF 36F0: FFFFFFFF 36F4: FFFFFFFF 36F8: FFFFFFFF 36FC: FFFFFFFF 3700: FFFFFFFF 3704: FFFFFFFF 3708: FFFFFFFF 370C: FFFFFFFF 3710: FFFFFFFF 3714: FFFFFFFF 3718: FFFFFFFF 371C: FFFFFFFF 3720: FFFFFFFF 3724: FFFFFFFF 3728: FFFFFFFF 372C: FFFFFFFF 3730: FFFFFFFF 3734: FFFFFFFF 3738: FFFFFFFF 373C: FFFFFFFF 3740: FFFFFFFF 3744: FFFFFFFF 3748: FFFFFFFF 374C: FFFFFFFF 3750: FFFFFFFF 3754: FFFFFFFF 3758: FFFFFFFF 375C: FFFFFFFF 3760: FFFFFFFF 3764: FFFFFFFF 3768: FFFFFFFF 376C: FFFFFFFF 3770: FFFFFFFF 3774: FFFFFFFF 3778: FFFFFFFF 377C: FFFFFFFF 3780: FFFFFFFF 3784: FFFFFFFF 3788: FFFFFFFF 378C: FFFFFFFF 3790: FFFFFFFF 3794: FFFFFFFF 3798: FFFFFFFF 379C: FFFFFFFF 37A0: FFFFFFFF 37A4: FFFFFFFF 37A8: FFFFFFFF 37AC: FFFFFFFF 37B0: FFFFFFFF 37B4: FFFFFFFF 37B8: FFFFFFFF 37BC: FFFFFFFF 37C0: FFFFFFFF 37C4: FFFFFFFF 37C8: FFFFFFFF 37CC: FFFFFFFF 37D0: FFFFFFFF 37D4: FFFFFFFF 37D8: FFFFFFFF 37DC: FFFFFFFF 37E0: FFFFFFFF 37E4: FFFFFFFF 37E8: FFFFFFFF 37EC: FFFFFFFF 37F0: FFFFFFFF 37F4: FFFFFFFF 37F8: FFFFFFFF 37FC: FFFFFFFF 3800: FFFFFFFF 3804: FFFFFFFF 3808: FFFFFFFF 380C: FFFFFFFF 3810: FFFFFFFF 3814: FFFFFFFF 3818: FFFFFFFF 381C: FFFFFFFF 3820: FFFFFFFF 3824: FFFFFFFF 3828: FFFFFFFF 382C: FFFFFFFF 3830: FFFFFFFF 3834: FFFFFFFF 3838: FFFFFFFF 383C: FFFFFFFF 3840: FFFFFFFF 3844: FFFFFFFF 3848: FFFFFFFF 384C: FFFFFFFF 3850: FFFFFFFF 3854: FFFFFFFF 3858: FFFFFFFF 385C: FFFFFFFF 3860: FFFFFFFF 3864: FFFFFFFF 3868: FFFFFFFF 386C: FFFFFFFF 3870: FFFFFFFF 3874: FFFFFFFF 3878: FFFFFFFF 387C: FFFFFFFF 3880: FFFFFFFF 3884: FFFFFFFF 3888: FFFFFFFF 388C: FFFFFFFF 3890: FFFFFFFF 3894: FFFFFFFF 3898: FFFFFFFF 389C: FFFFFFFF 38A0: FFFFFFFF 38A4: FFFFFFFF 38A8: FFFFFFFF 38AC: FFFFFFFF 38B0: FFFFFFFF 38B4: FFFFFFFF 38B8: FFFFFFFF 38BC: FFFFFFFF 38C0: FFFFFFFF 38C4: FFFFFFFF 38C8: FFFFFFFF 38CC: FFFFFFFF 38D0: FFFFFFFF 38D4: FFFFFFFF 38D8: FFFFFFFF 38DC: FFFFFFFF 38E0: FFFFFFFF 38E4: FFFFFFFF 38E8: FFFFFFFF 38EC: FFFFFFFF 38F0: FFFFFFFF 38F4: FFFFFFFF 38F8: FFFFFFFF 38FC: FFFFFFFF 3900: FFFFFFFF 3904: FFFFFFFF 3908: FFFFFFFF 390C: FFFFFFFF 3910: FFFFFFFF 3914: FFFFFFFF 3918: FFFFFFFF 391C: FFFFFFFF 3920: FFFFFFFF 3924: FFFFFFFF 3928: FFFFFFFF 392C: FFFFFFFF 3930: FFFFFFFF 3934: FFFFFFFF 3938: FFFFFFFF 393C: FFFFFFFF 3940: FFFFFFFF 3944: FFFFFFFF 3948: FFFFFFFF 394C: FFFFFFFF 3950: FFFFFFFF 3954: FFFFFFFF 3958: FFFFFFFF 395C: FFFFFFFF 3960: FFFFFFFF 3964: FFFFFFFF 3968: FFFFFFFF 396C: FFFFFFFF 3970: FFFFFFFF 3974: FFFFFFFF 3978: FFFFFFFF 397C: FFFFFFFF 3980: FFFFFFFF 3984: FFFFFFFF 3988: FFFFFFFF 398C: FFFFFFFF 3990: FFFFFFFF 3994: FFFFFFFF 3998: FFFFFFFF 399C: FFFFFFFF 39A0: FFFFFFFF 39A4: FFFFFFFF 39A8: FFFFFFFF 39AC: FFFFFFFF 39B0: FFFFFFFF 39B4: FFFFFFFF 39B8: FFFFFFFF 39BC: FFFFFFFF 39C0: FFFFFFFF 39C4: FFFFFFFF 39C8: FFFFFFFF 39CC: FFFFFFFF 39D0: FFFFFFFF 39D4: FFFFFFFF 39D8: FFFFFFFF 39DC: FFFFFFFF 39E0: FFFFFFFF 39E4: FFFFFFFF 39E8: FFFFFFFF 39EC: FFFFFFFF 39F0: FFFFFFFF 39F4: FFFFFFFF 39F8: FFFFFFFF 39FC: FFFFFFFF 3A00: FFFFFFFF 3A04: FFFFFFFF 3A08: FFFFFFFF 3A0C: FFFFFFFF 3A10: FFFFFFFF 3A14: FFFFFFFF 3A18: FFFFFFFF 3A1C: FFFFFFFF 3A20: FFFFFFFF 3A24: FFFFFFFF 3A28: FFFFFFFF 3A2C: FFFFFFFF 3A30: FFFFFFFF 3A34: FFFFFFFF 3A38: FFFFFFFF 3A3C: FFFFFFFF 3A40: FFFFFFFF 3A44: FFFFFFFF 3A48: FFFFFFFF 3A4C: FFFFFFFF 3A50: FFFFFFFF 3A54: FFFFFFFF 3A58: FFFFFFFF 3A5C: FFFFFFFF 3A60: FFFFFFFF 3A64: FFFFFFFF 3A68: FFFFFFFF 3A6C: FFFFFFFF 3A70: FFFFFFFF 3A74: FFFFFFFF 3A78: FFFFFFFF 3A7C: FFFFFFFF 3A80: FFFFFFFF 3A84: FFFFFFFF 3A88: FFFFFFFF 3A8C: FFFFFFFF 3A90: FFFFFFFF 3A94: FFFFFFFF 3A98: FFFFFFFF 3A9C: FFFFFFFF 3AA0: FFFFFFFF 3AA4: FFFFFFFF 3AA8: FFFFFFFF 3AAC: FFFFFFFF 3AB0: FFFFFFFF 3AB4: FFFFFFFF 3AB8: FFFFFFFF 3ABC: FFFFFFFF 3AC0: FFFFFFFF 3AC4: FFFFFFFF 3AC8: FFFFFFFF 3ACC: FFFFFFFF 3AD0: FFFFFFFF 3AD4: FFFFFFFF 3AD8: FFFFFFFF 3ADC: FFFFFFFF 3AE0: FFFFFFFF 3AE4: FFFFFFFF 3AE8: FFFFFFFF 3AEC: FFFFFFFF 3AF0: FFFFFFFF 3AF4: FFFFFFFF 3AF8: FFFFFFFF 3AFC: FFFFFFFF 3B00: FFFFFFFF 3B04: FFFFFFFF 3B08: FFFFFFFF 3B0C: FFFFFFFF 3B10: FFFFFFFF 3B14: FFFFFFFF 3B18: FFFFFFFF 3B1C: FFFFFFFF 3B20: FFFFFFFF 3B24: FFFFFFFF 3B28: FFFFFFFF 3B2C: FFFFFFFF 3B30: FFFFFFFF 3B34: FFFFFFFF 3B38: FFFFFFFF 3B3C: FFFFFFFF 3B40: FFFFFFFF 3B44: FFFFFFFF 3B48: FFFFFFFF 3B4C: FFFFFFFF 3B50: FFFFFFFF 3B54: FFFFFFFF 3B58: FFFFFFFF 3B5C: FFFFFFFF 3B60: FFFFFFFF 3B64: FFFFFFFF 3B68: FFFFFFFF 3B6C: FFFFFFFF 3B70: FFFFFFFF 3B74: FFFFFFFF 3B78: FFFFFFFF 3B7C: FFFFFFFF 3B80: FFFFFFFF 3B84: FFFFFFFF 3B88: FFFFFFFF 3B8C: FFFFFFFF 3B90: FFFFFFFF 3B94: FFFFFFFF 3B98: FFFFFFFF 3B9C: FFFFFFFF 3BA0: FFFFFFFF 3BA4: FFFFFFFF 3BA8: FFFFFFFF 3BAC: FFFFFFFF 3BB0: FFFFFFFF 3BB4: FFFFFFFF 3BB8: FFFFFFFF 3BBC: FFFFFFFF 3BC0: FFFFFFFF 3BC4: FFFFFFFF 3BC8: FFFFFFFF 3BCC: FFFFFFFF 3BD0: FFFFFFFF 3BD4: FFFFFFFF 3BD8: FFFFFFFF 3BDC: FFFFFFFF 3BE0: FFFFFFFF 3BE4: FFFFFFFF 3BE8: FFFFFFFF 3BEC: FFFFFFFF 3BF0: FFFFFFFF 3BF4: FFFFFFFF 3BF8: FFFFFFFF 3BFC: FFFFFFFF 3C00: FFFFFFFF 3C04: FFFFFFFF 3C08: FFFFFFFF 3C0C: FFFFFFFF 3C10: FFFFFFFF 3C14: FFFFFFFF 3C18: FFFFFFFF 3C1C: FFFFFFFF 3C20: FFFFFFFF 3C24: FFFFFFFF 3C28: FFFFFFFF 3C2C: FFFFFFFF 3C30: FFFFFFFF 3C34: FFFFFFFF 3C38: FFFFFFFF 3C3C: FFFFFFFF 3C40: FFFFFFFF 3C44: FFFFFFFF 3C48: FFFFFFFF 3C4C: FFFFFFFF 3C50: FFFFFFFF 3C54: FFFFFFFF 3C58: FFFFFFFF 3C5C: FFFFFFFF 3C60: FFFFFFFF 3C64: FFFFFFFF 3C68: FFFFFFFF 3C6C: FFFFFFFF 3C70: FFFFFFFF 3C74: FFFFFFFF 3C78: FFFFFFFF 3C7C: FFFFFFFF 3C80: FFFFFFFF 3C84: FFFFFFFF 3C88: FFFFFFFF 3C8C: FFFFFFFF 3C90: FFFFFFFF 3C94: FFFFFFFF 3C98: FFFFFFFF 3C9C: FFFFFFFF 3CA0: FFFFFFFF 3CA4: FFFFFFFF 3CA8: FFFFFFFF 3CAC: FFFFFFFF 3CB0: FFFFFFFF 3CB4: FFFFFFFF 3CB8: FFFFFFFF 3CBC: FFFFFFFF 3CC0: FFFFFFFF 3CC4: FFFFFFFF 3CC8: FFFFFFFF 3CCC: FFFFFFFF 3CD0: FFFFFFFF 3CD4: FFFFFFFF 3CD8: FFFFFFFF 3CDC: FFFFFFFF 3CE0: FFFFFFFF 3CE4: FFFFFFFF 3CE8: FFFFFFFF 3CEC: FFFFFFFF 3CF0: FFFFFFFF 3CF4: FFFFFFFF 3CF8: FFFFFFFF 3CFC: FFFFFFFF 3D00: FFFFFFFF 3D04: FFFFFFFF 3D08: FFFFFFFF 3D0C: FFFFFFFF 3D10: FFFFFFFF 3D14: FFFFFFFF 3D18: FFFFFFFF 3D1C: FFFFFFFF 3D20: FFFFFFFF 3D24: FFFFFFFF 3D28: FFFFFFFF 3D2C: FFFFFFFF 3D30: FFFFFFFF 3D34: FFFFFFFF 3D38: FFFFFFFF 3D3C: FFFFFFFF 3D40: FFFFFFFF 3D44: FFFFFFFF 3D48: FFFFFFFF 3D4C: FFFFFFFF 3D50: FFFFFFFF 3D54: FFFFFFFF 3D58: FFFFFFFF 3D5C: FFFFFFFF 3D60: FFFFFFFF 3D64: FFFFFFFF 3D68: FFFFFFFF 3D6C: FFFFFFFF 3D70: FFFFFFFF 3D74: FFFFFFFF 3D78: FFFFFFFF 3D7C: FFFFFFFF 3D80: FFFFFFFF 3D84: FFFFFFFF 3D88: FFFFFFFF 3D8C: FFFFFFFF 3D90: FFFFFFFF 3D94: FFFFFFFF 3D98: FFFFFFFF 3D9C: FFFFFFFF 3DA0: FFFFFFFF 3DA4: FFFFFFFF 3DA8: FFFFFFFF 3DAC: FFFFFFFF 3DB0: FFFFFFFF 3DB4: FFFFFFFF 3DB8: FFFFFFFF 3DBC: FFFFFFFF 3DC0: FFFFFFFF 3DC4: FFFFFFFF 3DC8: FFFFFFFF 3DCC: FFFFFFFF 3DD0: FFFFFFFF 3DD4: FFFFFFFF 3DD8: FFFFFFFF 3DDC: FFFFFFFF 3DE0: FFFFFFFF 3DE4: FFFFFFFF 3DE8: FFFFFFFF 3DEC: FFFFFFFF 3DF0: FFFFFFFF 3DF4: FFFFFFFF 3DF8: FFFFFFFF 3DFC: FFFFFFFF 3E00: FFFFFFFF 3E04: FFFFFFFF 3E08: FFFFFFFF 3E0C: FFFFFFFF 3E10: FFFFFFFF 3E14: FFFFFFFF 3E18: FFFFFFFF 3E1C: FFFFFFFF 3E20: FFFFFFFF 3E24: FFFFFFFF 3E28: FFFFFFFF 3E2C: FFFFFFFF 3E30: FFFFFFFF 3E34: FFFFFFFF 3E38: FFFFFFFF 3E3C: FFFFFFFF 3E40: FFFFFFFF 3E44: FFFFFFFF 3E48: FFFFFFFF 3E4C: FFFFFFFF 3E50: FFFFFFFF 3E54: FFFFFFFF 3E58: FFFFFFFF 3E5C: FFFFFFFF 3E60: FFFFFFFF 3E64: FFFFFFFF 3E68: FFFFFFFF 3E6C: FFFFFFFF 3E70: FFFFFFFF 3E74: FFFFFFFF 3E78: FFFFFFFF 3E7C: FFFFFFFF 3E80: FFFFFFFF 3E84: FFFFFFFF 3E88: FFFFFFFF 3E8C: FFFFFFFF 3E90: FFFFFFFF 3E94: FFFFFFFF 3E98: FFFFFFFF 3E9C: FFFFFFFF 3EA0: FFFFFFFF 3EA4: FFFFFFFF 3EA8: FFFFFFFF 3EAC: FFFFFFFF 3EB0: FFFFFFFF 3EB4: FFFFFFFF 3EB8: FFFFFFFF 3EBC: FFFFFFFF 3EC0: FFFFFFFF 3EC4: FFFFFFFF 3EC8: FFFFFFFF 3ECC: FFFFFFFF 3ED0: FFFFFFFF 3ED4: FFFFFFFF 3ED8: FFFFFFFF 3EDC: FFFFFFFF 3EE0: FFFFFFFF 3EE4: FFFFFFFF 3EE8: FFFFFFFF 3EEC: FFFFFFFF 3EF0: FFFFFFFF 3EF4: FFFFFFFF 3EF8: FFFFFFFF 3EFC: FFFFFFFF 3F00: FFFFFFFF 3F04: FFFFFFFF 3F08: FFFFFFFF 3F0C: FFFFFFFF 3F10: FFFFFFFF 3F14: FFFFFFFF 3F18: FFFFFFFF 3F1C: FFFFFFFF 3F20: FFFFFFFF 3F24: FFFFFFFF 3F28: FFFFFFFF 3F2C: FFFFFFFF 3F30: FFFFFFFF 3F34: FFFFFFFF 3F38: FFFFFFFF 3F3C: FFFFFFFF 3F40: FFFFFFFF 3F44: FFFFFFFF 3F48: FFFFFFFF 3F4C: FFFFFFFF 3F50: FFFFFFFF 3F54: FFFFFFFF 3F58: FFFFFFFF 3F5C: FFFFFFFF 3F60: FFFFFFFF 3F64: FFFFFFFF 3F68: FFFFFFFF 3F6C: FFFFFFFF 3F70: FFFFFFFF 3F74: FFFFFFFF 3F78: FFFFFFFF 3F7C: FFFFFFFF 3F80: FFFFFFFF 3F84: FFFFFFFF 3F88: FFFFFFFF 3F8C: FFFFFFFF 3F90: FFFFFFFF 3F94: FFFFFFFF 3F98: FFFFFFFF 3F9C: FFFFFFFF 3FA0: FFFFFFFF 3FA4: FFFFFFFF 3FA8: FFFFFFFF 3FAC: FFFFFFFF 3FB0: FFFFFFFF 3FB4: FFFFFFFF 3FB8: FFFFFFFF 3FBC: FFFFFFFF 3FC0: FFFFFFFF 3FC4: FFFFFFFF 3FC8: FFFFFFFF 3FCC: FFFFFFFF 3FD0: FFFFFFFF 3FD4: FFFFFFFF 3FD8: FFFFFFFF 3FDC: FFFFFFFF 3FE0: FFFFFFFF 3FE4: FFFFFFFF 3FE8: FFFFFFFF 3FEC: FFFFFFFF 3FF0: FFFFFFFF 3FF4: FFFFFFFF 3FF8: FFFFFFFF 3FFC: FFFFFFFF 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_end equ $5B23 ; = 23331 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 v_mem_get_free_total equ $0E77 ; = 3703 v_mem_get_free equ $0E7A ; = 3706 mem_init equ $0E81 ; = 3713 v_mem_compact equ $0EA0 ; = 3744 mem_compact_no_exx equ $0EA2 ; = 3746 mem_compact equ $0EA2 ; = 3746 mc0 equ $0EB4 ; = 3764 mc1 equ $0EE1 ; = 3809 mem_compact_loop1 equ $0EFA ; = 3834 mc1e equ $0EFA ; = 3834 mc2 equ $0F05 ; = 3845 mc3 equ $0F0F ; = 3855 mc2ee equ $0F22 ; = 3874 mem_compact_loop2 equ $0F23 ; = 3875 mc2e equ $0F23 ; = 3875 mem_get_free_total_no_exx equ $0F2E ; = 3886 mem_get_free_total equ $0F2E ; = 3886 mem_get_free_no_exx equ $0F31 ; = 3889 mem_get_free equ $0F31 ; = 3889 mem_get_size_and_address equ $0F44 ; = 3908 mem_get_address_no_exx equ $0F4D ; = 3917 mem_get_address equ $0F4D ; = 3917 mem_get_size_no_exx equ $0F54 ; = 3924 mem_get_size equ $0F54 ; = 3924 mem_assert_size_no_exx equ $0F5E ; = 3934 mem_assert_size equ $0F5E ; = 3934 mem_assert_free_no_exx equ $0F63 ; = 3939 mem_assert_free equ $0F63 ; = 3939 mas0 equ $0F6F ; = 3951 mem_heap_pop_handle_no_exx equ $0F72 ; = 3954 mem_heap_pop_handle equ $0F72 ; = 3954 mem_heap_peek_handle_no_exx equ $0F7B ; = 3963 mem_heap_peek_handle equ $0F7B ; = 3963 mem_heap_new_handle equ $0F81 ; = 3969 mem_new_handle equ $0F8E ; = 3982 mem_new_handle_quick equ $0F9C ; = 3996 mnh1 equ $0FA7 ; = 4007 mem_realloc_no_exx equ $0FB7 ; = 4023 mem_realloc equ $0FB7 ; = 4023 mem_heap_alloc equ $0FD2 ; = 4050 mem_alloc equ $0FDA ; = 4058 ma2 equ $0FE0 ; = 4064 mem_set_empty_data equ $0FF9 ; = 4089 ma3 equ $0FF9 ; = 4089 mem_heap_push_data_no_exx equ $1001 ; = 4097 mem_heap_push_data equ $1001 ; = 4097 mem_save_data equ $1007 ; = 4103 msd1 equ $100B ; = 4107 mem_restore_data equ $1015 ; = 4117 mem_dealloc equ $1019 ; = 4121 mem_heap_pop_data_no_exx equ $101E ; = 4126 mem_heap_pop_data equ $101E ; = 4126 mem_copy_data_to_de equ $1022 ; = 4130 ldir_if_nz equ $1025 ; = 4133 ldir equ $1028 ; = 4136 mem_heap_push_handle equ $102B ; = 4139 mem_heap_pick_handle equ $103D ; = 4157 mem_heap_swap_handles equ $1046 ; = 4166 v_string equ $105B ; = 4187 vs1 equ $1060 ; = 4192 v_straddr equ $1076 ; = 4214 v_strlen equ $1081 ; = 4225 v_dupstr equ $108E ; = 4238 v_dropstr equ $1096 ; = 4246 v_unsharestr equ $109B ; = 4251 v_nipstr equ $10A5 ; = 4261 v_swapstr equ $10AD ; = 4269 v_pickstr equ $10B2 ; = 4274 v_upperstr equ $10BA ; = 4282 us2 equ $10C6 ; = 4294 us3 equ $10D0 ; = 4304 us1 equ $10D1 ; = 4305 v_lowerstr equ $10DA ; = 4314 ls2 equ $10E6 ; = 4326 ls3 equ $10F0 ; = 4336 ls1 equ $10F1 ; = 4337 v_charstr equ $10FA ; = 4346 v_charcode equ $1109 ; = 4361 v_spacestr equ $111B ; = 4379 v_emptystr equ $112A ; = 4394 v_initstrvar equ $1138 ; = 4408 v_killstrvar equ $1141 ; = 4417 v_peekstr equ $114C ; = 4428 v_pokestr equ $1157 ; = 4439 v_pushdata equ $1169 ; = 4457 v_popdata equ $1174 ; = 4468 v_catstr equ $117A ; = 4474 str_validate_hl_and_de equ $11B5 ; = 4533 str_validate_index equ $11BA ; = 4538 vd1 equ $11C5 ; = 4549 v_quicksubstr equ $11C9 ; = 4553 vqss1 equ $11CF ; = 4559 v_midstr equ $11E6 ; = 4582 v_substr equ $11EA ; = 4586 vss0 equ $1200 ; = 4608 v_leftstr equ $120A ; = 4618 v_rightstr equ $121A ; = 4634 mempack_end equ $122E ; = 4654 vip_start equ $122E ; = 4654 v_scratch equ $5B25 ; = 23333 init_vip equ $122E ; = 4654 vip_dis equ $122F ; = 4655 v_umax equ $1235 ; = 4661 vum1 equ $1237 ; = 4663 v_umin equ $123F ; = 4671 vum2 equ $1241 ; = 4673 v_max equ $1249 ; = 4681 v_min equ $1251 ; = 4689 v_if equ $1259 ; = 4697 v_iff equ $1260 ; = 4704 v_ifff equ $1267 ; = 4711 skip3 equ $126C ; = 4716 skip2 equ $126D ; = 4717 skip1 equ $126E ; = 4718 v_byte equ $1271 ; = 4721 v_peekb equ $1275 ; = 4725 bp1 equ $1276 ; = 4726 v_number equ $127C ; = 4732 v_peek equ $1285 ; = 4741 v_poke equ $128B ; = 4747 v_pokeb equ $1293 ; = 4755 v_over equ $1299 ; = 4761 v_pick equ $129F ; = 4767 v_setbit equ $12A8 ; = 4776 vsb1 equ $12B5 ; = 4789 v_clrbit equ $12B9 ; = 4793 vcb1 equ $12C6 ; = 4806 v_jump equ $12CA ; = 4810 v_bra equ $12D1 ; = 4817 v_bra_if equ $12DC ; = 4828 v_bra_ifnot equ $12E4 ; = 4836 v_opcode equ $12EC ; = 4844 v_call equ $12F3 ; = 4851 v_jp_calc equ $12FD ; = 4861 v_exit equ $12FD ; = 4861 v_call_calc equ $1302 ; = 4866 v_penter equ $1309 ; = 4873 v_preturn equ $1321 ; = 4897 v_pexit equ $132F ; = 4911 pex1 equ $1335 ; = 4917 v_lvar equ $1339 ; = 4921 v_lvar_poke equ $1348 ; = 4936 v_pp equ $135A ; = 4954 v_mm equ $1363 ; = 4963 v_pp_peek equ $136E ; = 4974 v_mm_peek equ $1378 ; = 4984 v_peek_pp equ $1382 ; = 4994 v_peek_mm equ $138D ; = 5005 v_and equ $1398 ; = 5016 v_or equ $13A1 ; = 5025 v_xor equ $13AA ; = 5034 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 string equ $0098 ; = 152 strlen equ $009B ; = 155 catstr equ $009E ; = 158 leftstr equ $00A1 ; = 161 rightstr equ $00A4 ; = 164 midstr equ $00A7 ; = 167 substr equ $00AA ; = 170 upperstr equ $00AD ; = 173 lowerstr equ $00B0 ; = 176 charstr equ $00B3 ; = 179 hex2str equ $00B6 ; = 182 hex4str equ $00B9 ; = 185 numstr equ $00BC ; = 188 print equ $00BF ; = 191 printchar equ $00C2 ; = 194 printdec equ $00C5 ; = 197 printhex equ $00C8 ; = 200 bit equ $00CB ; = 203 setbit equ $00CE ; = 206 clrbit equ $00D1 ; = 209 neg equ $00D4 ; = 212 cpl equ $00D5 ; = 213 swap equ $00D7 ; = 215 add equ $00D9 ; = 217 sub equ $00DB ; = 219 eq equ $00DD ; = 221 ne equ $00DF ; = 223 gt equ $00E1 ; = 225 ge equ $00E3 ; = 227 lt equ $00E5 ; = 229 le equ $00E7 ; = 231 not equ $00E9 ; = 233 bool equ $00EB ; = 235 getkey equ $00ED ; = 237 waitkey equ $00EF ; = 239 abs equ $00F1 ; = 241 lvar_peek equ $00F3 ; = 243 v_tab_end equ $14F4 ; = 5364 v_lvar_peek_ctd equ $14F4 ; = 5364 v_abs equ $1503 ; = 5379 v_neg equ $1508 ; = 5384 v_cpl equ $1509 ; = 5385 v_swap equ $1512 ; = 5394 v_add equ $1517 ; = 5399 v_sub equ $151C ; = 5404 vsub1 equ $151E ; = 5406 v_ne equ $1523 ; = 5411 set1 equ $1529 ; = 5417 v_eq equ $152E ; = 5422 set0 equ $1534 ; = 5428 v_gt equ $1539 ; = 5433 v_lt equ $153C ; = 5436 vlt1 equ $1542 ; = 5442 v_le equ $1548 ; = 5448 v_ge equ $154B ; = 5451 vge1 equ $1551 ; = 5457 v_not equ $1557 ; = 5463 v_bool equ $155D ; = 5469 v_getkey equ $1563 ; = 5475 v_waitkey equ $1568 ; = 5480 vwk1 equ $156B ; = 5483 v_bit equ $1571 ; = 5489 vb1 equ $1581 ; = 5505 up_vz_mult_quick equ $1586 ; = 5510 upvz1 equ $158F ; = 5519 abs_de equ $159A ; = 5530 neg_de equ $159D ; = 5533 v_mult equ $15A5 ; = 5541 m2 equ $15BC ; = 5564 m3 equ $15BD ; = 5565 m1 equ $15C6 ; = 5574 v_div equ $15CF ; = 5583 vd3 equ $15D6 ; = 5590 v_rem equ $15DE ; = 5598 vr1 equ $15E5 ; = 5605 div_hl_de equ $15EC ; = 5612 div2 equ $15F3 ; = 5619 div1 equ $15FF ; = 5631 rnd_seed equ $5B2B ; = 23339 v_rnd equ $1603 ; = 5635 rnd1 equ $160C ; = 5644 v_shl equ $1625 ; = 5669 vshl4 equ $1633 ; = 5683 vshl2 equ $1637 ; = 5687 vshl3 equ $163B ; = 5691 v_shr equ $163E ; = 5694 vshr4 equ $164C ; = 5708 vshr2 equ $1650 ; = 5712 vshr3 equ $1657 ; = 5719 v_hpeek equ $165A ; = 5722 v_printchar equ $1664 ; = 5732 v_print equ $166B ; = 5739 v_printdec equ $1675 ; = 5749 v_printhex equ $167C ; = 5756 v_numstr equ $1683 ; = 5763 v_hex4str equ $169C ; = 5788 v_hex2str equ $16AA ; = 5802 vhx2 equ $16B7 ; = 5815 vip_end equ $16BB ; = 5819 ram_test equ $16BB ; = 5819 cs1 equ $16C0 ; = 5824 cs2 equ $16D0 ; = 5840 cs3 equ $16DB ; = 5851 cs5 equ $16E8 ; = 5864 ram_broken_1 equ $16F2 ; = 5874 ram_broken_2 equ $16F8 ; = 5880 init_errors equ $16FE ; = 5886 errno equ $5B2E ; = 23342 error_msg_handle equ $5B2F ; = 23343 error_handler equ $5B31 ; = 23345 noerror equ $0000 ; = 0 error_message equ $0001 ; = 1 error_oomem equ $0002 ; = 2 error_notester equ $0003 ; = 3 error_messages equ $1704 ; = 5892 abort_oomem equ $1728 ; = 5928 abort equ $172A ; = 5930 set_error_handler equ $1731 ; = 5937 get_error_handler equ $1735 ; = 5941 set_error_message equ $1739 ; = 5945 sem1 equ $1743 ; = 5955 print_error_message equ $1756 ; = 5974 pem1 equ $176E ; = 5998 pem2 equ $1773 ; = 6003 up_show_error equ $1779 ; = 6009 oomem_handler equ $1799 ; = 6041 oo_oo equ $17AA ; = 6058 msg_presskey equ $180D ; = 6157 msg_ok equ $181D ; = 6173 msg_yes equ $1822 ; = 6178 msg_no equ $1828 ; = 6184 msg_cancel equ $182D ; = 6189 msg_enter equ $1836 ; = 6198 open_alert equ $183E ; = 6206 oa1 equ $187B ; = 6267 oa2 equ $1881 ; = 6273 alert_save_pixels equ $189B ; = 6299 alert_set_main_text equ $18AB ; = 6315 absmt1 equ $18B9 ; = 6329 absmt5 equ $18C0 ; = 6336 absmt2 equ $18CB ; = 6347 absmt4 equ $18D0 ; = 6352 absmt3 equ $18E4 ; = 6372 up_print_some_text equ $18ED ; = 6381 alert_add_button equ $1905 ; = 6405 close_alert equ $193D ; = 6461 ca3 equ $193F ; = 6463 ca_attr equ $194E ; = 6478 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 $1953 ; = 6483 skeys equ $197B ; = 6523 ckeys equ $19A3 ; = 6563 keys_end equ $19CB ; = 6603 init_keyboard equ $19CB ; = 6603 wait_newkey equ $19CC ; = 6604 wait_inkey equ $19CF ; = 6607 flush_inkey equ $19D6 ; = 6614 get_inkey equ $19E6 ; = 6630 kfs_x equ $1A00 ; = 6656 key_inkey equ $5B33 ; = 23347 key_oldkey equ $5B35 ; = 23349 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 $5B36 ; = 23350 key_guardtime equ $0002 ; = 2 key_startdelay equ $000A ; = 10 key_repeatdelay equ $0004 ; = 4 irpt_scan_keyboard equ $1A09 ; = 6665 isk0 equ $1A19 ; = 6681 isk01 equ $1A1D ; = 6685 isk001 equ $1A1F ; = 6687 isk4 equ $1A2C ; = 6700 isk3 equ $1A31 ; = 6705 isk5 equ $1A3E ; = 6718 isk7 equ $1A4C ; = 6732 isk61 equ $1A52 ; = 6738 isk8 equ $1A5B ; = 6747 isk10 equ $1A6F ; = 6767 isk6 equ $1A72 ; = 6770 isk11 equ $1A78 ; = 6776 isk111 equ $1A8A ; = 6794 isk112 equ $1A9B ; = 6811 isk13 equ $1AA1 ; = 6817 isk14 equ $1AA5 ; = 6821 io_pins equ $5B37 ; = 23351 io_flags equ $5B38 ; = 23352 io_flag_irpt equ $0007 ; = 7 io_bits_table equ $5B39 ; = 23353 io_bits_l equ $5B39 ; = 23353 io_bits_A8 equ $5B39 ; = 23353 io_bits_A9 equ $5B3D ; = 23357 io_bits_A10 equ $5B41 ; = 23361 io_bits_r equ $5B45 ; = 23365 io_bits_A11 equ $5B45 ; = 23365 io_bits_A12 equ $5B49 ; = 23369 io_bits_A13 equ $5B4D ; = 23373 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 $5B51 ; = 23377 ic_pin_type equ $5C71 ; = 23665 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 $1AAF ; = 6831 set_pin_type equ $1AB6 ; = 6838 ic_set_pin_type_for_current_pin equ $1ABD ; = 6845 ic_draw_all_pin_types equ $1AC9 ; = 6857 icdap1 equ $1ACB ; = 6859 ic_draw_pin_type_for_current_pin equ $1AD4 ; = 6868 ic_draw_pin_type equ $1AD7 ; = 6871 icdp1 equ $1AE9 ; = 6889 ic_pin_type_text_r equ $1B12 ; = 6930 icptr1 equ $1B1A ; = 6938 icptr2 equ $1B1C ; = 6940 icptr3 equ $1B1E ; = 6942 icptr4 equ $1B20 ; = 6944 icptr5 equ $1B22 ; = 6946 icptr6 equ $1B24 ; = 6948 icptr7 equ $1B27 ; = 6951 icptr8 equ $1B2A ; = 6954 ic_pin_type_text_l equ $1B2D ; = 6957 icptl1 equ $1B35 ; = 6965 icptl2 equ $1B39 ; = 6969 icptl3 equ $1B3D ; = 6973 icptl4 equ $1B41 ; = 6977 icptl5 equ $1B45 ; = 6981 icptl6 equ $1B49 ; = 6985 icptl7 equ $1B4E ; = 6990 icptl8 equ $1B53 ; = 6995 calc_hl_mask_a_for_pin equ $1B58 ; = 7000 calc_attr_hl_for_name equ $1B72 ; = 7026 calc_attr_hl_for_type equ $1B7C ; = 7036 calc_attr_hl_for_obit equ $1B86 ; = 7046 ca2 equ $1B8E ; = 7054 ca1 equ $1B91 ; = 7057 calc_pin_from_hilight equ $1B95 ; = 7061 calc_pin_from_rowcol equ $1B99 ; = 7065 test_col_c_is_obit equ $1BA2 ; = 7074 test_col_c_is_name equ $1BA9 ; = 7081 test_col_c_is_type equ $1BB0 ; = 7088 ic_hilight_row_col equ $5CA1 ; = 23713 ic_hilight_col equ $5CA1 ; = 23713 ic_hilight_row equ $5CA2 ; = 23714 ic_hilight_size_attr equ $5CA3 ; = 23715 ic_hilight_size equ $5CA3 ; = 23715 ic_hilight_attr equ $5CA4 ; = 23716 ic_clear_hilight equ $1BB7 ; = 7095 icca1 equ $1BCA ; = 7114 icca3 equ $1BCF ; = 7119 ic_set_hilight equ $1BD1 ; = 7121 icsh1 equ $1BDC ; = 7132 ic_size_tab equ $1BEB ; = 7147 ic_col0_tab equ $1BFB ; = 7163 ic_next_tab equ $1C0B ; = 7179 ic_validate_hilight equ $1C1B ; = 7195 ic_get_size_for_col equ $1C27 ; = 7207 ic_validate_col equ $1C32 ; = 7218 ic_validate_row equ $1C3F ; = 7231 ic_move_hilight_down equ $1C52 ; = 7250 ic_move_hilight equ $1C54 ; = 7252 ic_up equ $1C7D ; = 7293 ic_down equ $1C7F ; = 7295 ic_left equ $1C81 ; = 7297 ic_right equ $1C83 ; = 7299 init_pin_display equ $1C8E ; = 7310 stop_pin_display equ $1C8E ; = 7310 start_pin_display equ $1C96 ; = 7318 resume_pin_display equ $1C9B ; = 7323 ic_force_redraw equ $1CA2 ; = 7330 icfr1 equ $1CA9 ; = 7337 ic_detect_size equ $1CB6 ; = 7350 icds1 equ $1CBC ; = 7356 icds2 equ $1CCA ; = 7370 ic_get_pin equ $1CD3 ; = 7379 ic_set_pin_to_cy equ $1CDF ; = 7391 ic_reset_current_pin equ $1CE1 ; = 7393 ic_reset_pin equ $1CE8 ; = 7400 ics1 equ $1CEE ; = 7406 ics2 equ $1CEF ; = 7407 ic_set_current_pin equ $1CF3 ; = 7411 ic_set_pin equ $1CFA ; = 7418 ics3 equ $1CFB ; = 7419 ic_toggle_current_pin equ $1D01 ; = 7425 ic_toggle_pin equ $1D08 ; = 7432 ic_trigger_current_pin equ $1D0F ; = 7439 ic_trigger_pin equ $1D16 ; = 7446 ic_calc_ahlbc_for_pin_a_no_exx equ $1D20 ; = 7456 ic_calc_ahlbc_for_pin_a equ $1D20 ; = 7456 io_sync_iobits equ $1D3E ; = 7486 io_sync_ibits equ $1D41 ; = 7489 isi1 equ $1D4B ; = 7499 io_sync_obits equ $1D55 ; = 7509 iso1 equ $1D5F ; = 7519 ic_test_tester_present equ $1D69 ; = 7529 iso3 equ $1D7A ; = 7546 iso4 equ $1D83 ; = 7555 iso5 equ $1D96 ; = 7574 iso55 equ $1D99 ; = 7577 msg_tester_broken equ $1DBB ; = 7611 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 $1DDA ; = 7642 ic_switch_vcc_off equ $1DE2 ; = 7650 iso2 equ $1DF1 ; = 7665 ic_render_pin_no_exx equ $1DF9 ; = 7673 ic_render_pin equ $1DF9 ; = 7673 icrp1 equ $1E07 ; = 7687 char_0 equ $1E11 ; = 7697 char_1 equ $1E18 ; = 7704 ic_render_8_pins_left_no_exx equ $1E20 ; = 7712 ic_render_8_pins_left equ $1E20 ; = 7712 icr2 equ $1E31 ; = 7729 icr1 equ $1E34 ; = 7732 ic_render_8_pins_right_no_exx equ $1E3F ; = 7743 ic_render_8_pins_right equ $1E3F ; = 7743 icr4 equ $1E4F ; = 7759 irpt_pin_display equ $1E5F ; = 7775 ic_update_all_pins_no_exx equ $1E65 ; = 7781 ic_update_all_pins equ $1E65 ; = 7781 icr5 equ $1E73 ; = 7795 timer_cell equ $5CA5 ; = 23717 init_timer equ $1EA2 ; = 7842 irpt_timer equ $1EA3 ; = 7843 calc_strlen equ $1EAE ; = 7854 sl1 equ $1EB1 ; = 7857 vzdecstr equ $1EBA ; = 7866 decstr equ $1EC9 ; = 7881 decstr_max3digits equ $1EDB ; = 7899 decstr5 equ $1EEF ; = 7919 decstr4 equ $1EF5 ; = 7925 decstr3 equ $1EFB ; = 7931 decstr2 equ $1F01 ; = 7937 decstr1 equ $1F07 ; = 7943 ds equ $1F0A ; = 7946 ds1 equ $1F0D ; = 7949 hexstr4 equ $1F16 ; = 7958 hexstr2 equ $1F1D ; = 7965 hexstr1hi equ $1F24 ; = 7972 hexstr1 equ $1F28 ; = 7976 hs1 equ $1F32 ; = 7986 binstr16 equ $1F35 ; = 7989 binstr8 equ $1F3C ; = 7996 bs0 equ $1F3F ; = 7999 bs1 equ $1F40 ; = 8000 binstr4 equ $1F4B ; = 8011 deref_hl equ $1F50 ; = 8016 calc_hex_char_hi equ $1F55 ; = 8021 calc_hex_char equ $1F59 ; = 8025 mult_bc equ $1F63 ; = 8035 mult_ac equ $1F64 ; = 8036 mu2 equ $1F6C ; = 8044 mu1 equ $1F70 ; = 8048 calc_rbmask equ $1F78 ; = 8056 calc_bmask equ $1F79 ; = 8057 crfb2 equ $1F7D ; = 8061 calc_rnmask equ $1F84 ; = 8068 calc_nmask equ $1F85 ; = 8069 calc_lmask equ $1F8B ; = 8075 calc_rmask equ $1F93 ; = 8083 crfb1 equ $1F9B ; = 8091 masks equ $1F9F ; = 8095 bmasks equ $1F9F ; = 8095 nmasks equ $1FA7 ; = 8103 lmasks equ $1FAF ; = 8111 rmasks equ $1FB7 ; = 8119 vip_test equ $1FBF ; = 8127 vt1 equ $1FDD ; = 8157 vt2 equ $1FED ; = 8173 vt3 equ $1FFD ; = 8189 vt24 equ $200C ; = 8204 vt4 equ $201C ; = 8220 vt5 equ $202B ; = 8235 vt6 equ $203A ; = 8250 vt7 equ $204A ; = 8266 vt8 equ $205A ; = 8282 vt9 equ $206A ; = 8298 vt10 equ $2079 ; = 8313 vt11 equ $2088 ; = 8328 vt12 equ $2097 ; = 8343 vt13 equ $20A8 ; = 8360 vt14 equ $20B9 ; = 8377 vt15 equ $20C8 ; = 8392 vt16 equ $20DE ; = 8414 vt17 equ $20F3 ; = 8435 vt18 equ $210D ; = 8461 vt19 equ $2128 ; = 8488 vt20 equ $2143 ; = 8515 vt21 equ $215B ; = 8539 vt22 equ $2174 ; = 8564 vt23 equ $2192 ; = 8594 vt25 equ $21AE ; = 8622 vt26 equ $21C3 ; = 8643 vt27 equ $21DA ; = 8666 vt28 equ $21F0 ; = 8688 vt29 equ $2206 ; = 8710 sys_info_attr equ $0068 ; = 104 sys_info_h_attr equ $0027 ; = 39 system_info equ $2210 ; = 8720 press_any_key equ $236B ; = 9067 v_calc_min_stack_free equ $2381 ; = 9089 cms1 equ $2389 ; = 9097 print_obit_menu equ $2392 ; = 9106 print_type_menu equ $23DE ; = 9182 print_name_menu equ $2452 ; = 9298 free_test_menu equ $24C4 ; = 9412 ft1 equ $258A ; = 9610 set_pintype_input equ $25F7 ; = 9719 set_pintype_output equ $25FB ; = 9723 set_pintype_3state equ $25FF ; = 9727 set_pintype_oK equ $2603 ; = 9731 set_pintype_io equ $2607 ; = 9735 set_pintype_nc equ $260B ; = 9739 set_pintype_vcc equ $260F ; = 9743 set_pintype_gnd equ $2613 ; = 9747 set_pintype_unknown equ $2617 ; = 9751 spt1 equ $2619 ; = 9753 edit_pin_name equ $261F ; = 9759 set_pin_count equ $261F ; = 9759 edit_pin_info equ $261F ; = 9759 fetch_ic_info equ $261F ; = 9759 store_ic_info equ $261F ; = 9759 calc_checksum equ $261F ; = 9759 code_end equ $2620 ; = 9760 data_end equ $5CA8 ; = 23720