; ; I/O locations: ; equ ZX_KEYBOARD_PORT $FE ; A0 low equ ZX_NMI_GEN $FD ; A1 low equ ZX_PRINTER_PORT $FB ; A2 low ; ; Byte constants ; equ G007_INT_REG_VALUE_FOR_HI_RES_GRAPHICS $1F equ G007_INT_REG_VALUE_FOR_LO_RES_GRAPHICS $1E ; Dec. Hex. Bytes System Variables: G007 ; 8448 2100 Reserved for user defined characters ; 8703 21FF ; ; 8704 2200 Another page, possibly ; 8959 22FF ; Dec. Hex. Bytes System Variables: G007 ; 8960 2300 2 Offset of hi-res display file, less 9, from the D-FILE variable ; 8962 2302 2 Not used ; 8964 2304 2 Start address of last line of lo-res display file equ G007_DISPLAY_FILE_LESS_9 $2306 ; 8966 2306 2 Start address of hi-res display file, less 9 (used for video) equ G007_DISPLAY_ADDRESS $2308 ; 8968 2308 2 Start address of hi-res display file equ G007_TRIANGLE_TEXTURE $230A ; 8970 230A 2 Bytes defining triangle texture equ G007_CHAR_TABLE_ADDR_0_63; $230C ; 8972 230C 2 Character table address for CHR$0-63 equ G007_CHAR_TABLE_ADDR_128_159; $230E ; 8974 230E 2 Character table address for CHR$128-159 equ G007_PLOT_ROUTINES_VECTOR $2310 ; 8976 2310 2 Vector for additional plot routines equ G007_FLAG_0 $2312 ; 8978 2312 3 * Various flags equ G007_FLAG_1 $2313 equ G007_FLAG_2 $2314 equ G007_USR_DEF_CHR_TAB_LESS_256 $2315 ; 8981 2315 2 Address of user-defined character table, less 256 equ G007_READ_POINT_BYTE $2317 ; 8983 2317 1 "Read-point" byte. Non-zero if pixel is set. equ G007_DISPLAY_HEIGHT $2318 ; 8984 2318 1 * Display height, normally 192 equ G007_FLAG_3 $2319 ; 8985 2319 1 Flags equ G007_TEMP_BYTE_0 $231A ; 9886 231A 7 Temporary variables for PLOT routine. equ G007_TEMP_BYTE_1 $231B equ G007_TEMP_BYTE_2 $231C equ G007_TEMP_BYTE_3 $231D equ G007_TEMP_BYTE_4 $231E equ G007_TEMP_BYTE_5 $231F equ G007_TEMP_BYTE_6 $2320 equ G007_OUT_OF_RANGE_FLAGS $2321 ; 8993 2321 1 Plot out of range flags. Bit 7 = latest statement ; 8994 2322 1 Not used equ G007_PLOT_X $2323 ; 8995 2323 2 X co-ordinate for PLOT. Signed 16-bit equ G007_PLOT_Y $2325 ; 8997 2325 2 Y co-ordinate for PLOT. Signed 16-bit equ G007_PLOT_X_PREVIOUS_N1 $2327 ; 8999 2327 8 X and Y co-ordinates for previous two statements equ G007_PLOT_Y_PREVIOUS_N1 $2329 equ G007_PLOT_X_PREVIOUS_N2 $232B equ G007_PLOT_Y_PREVIOUS_N2 $232D equ G007_FLAG_4 $232F ; 9007 232F 1 Flags equ G007_ORIGIN_Y $2330 ; 9008 2330 2 Y co-ordinate of graphics origin equ G007_ORIGIN_X $2332 ; 9010 2332 2 X co-ordinate of graphics origin equ G007_LINE_TYPE $2334 ; 9012 2334 4 Bytes defining four line types equ G007_TEMP_BYTE_7 $2338 ; 9016 2338 2 Temporary variable for PLOT equ G007_TEMP_BYTE_8 $2339 ; ; THE KEY TABLES ; The 'unshifted' character codes 007E - 00A4 ; The 'shifted' character codes 00A5 - 00CB ; The 'function' character codes 00CC - 00F2 ; The 'graphic' character codes 00F3 - 0110 ; The 'token' tables 0111 - 01FB ; ; ZX BASIC ROM addresses ; equ RECLAIM_1 $0A5D equ REPORT_B $0EAD equ SET_FAST $02E7 equ NEW $03C3 equ LOC_ADDR $0918 equ ONE_SPACE $099B equ MAKE_ROOM $099E equ LINE_ADDR $09D8 equ CLS $0A2A equ PRINT $0ACF equ STK_TO_A $0C02 equ ? $0C9C equ ? $0CA0 ; []*BIOS ROM* equ INPUT_RE $0D6F ; ; ZX BASIC RAM addresses ; equ ERR_NR 4000 equ FLAGS 4001 equ ERR_SP 4002 equ RAMTOP 4004 equ MODE 4006 equ PPC 4007 equ VERSN 4009 equ E_PPC 400A equ D_FILE 400C equ DF_CC 400E equ VARS 4010 equ DEST 4012 equ E_LINE 4014 equ CH_ADD 4016 equ X_PTR 4018 equ STKBOT 401A equ STKEND 401C equ BERG 401E equ MEM 401F equ UNUSED_8 $4021 equ DF_SZ 4022 equ S_TOP 4023 equ LAST_K 4025 equ DEBOUNCE 4027 equ MARGIN 4028 equ NXTLIN 4029 equ NXT_LINE $4029 equ OLDPPC 402B equ FLAGX 402D equ STRLEN 402E equ T_ADDR 4030 equ SEED 4032 equ FRAMES 4034 equ COORDS 4036 equ PR_CC 4038 equ S_POSN 4039 equ CDFLAG 403B equ PRBUFF 403C equ MEMBOT 407B equ PROGRAM 407D equ UNUSED_16 $407B ; ; Start of G007 ROM ; ; ; 10240/12287 : 2800/2FFF G007_GET_PIXEL_ADDRESS_AND_MASK: ; 2800 2A;23;23 LD HL,(G007_PLOT_X) ; X co-ordinate for PLOT. Signed 16-bit. Fetch 16 bits L2803: 2803 3A;25;23 LD A,(G007_PLOT_Y) ; Y co-ordinate for PLOT. Signed 16-bit. Fetch 8 bits 2806 67 LD H,A ; and store in H L2807: 2807 EB EX DE,HL ; then swap it into D 2808 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) 280B 3D DEC A ; 280C 92 SUB D ; 280D 57 LD D,A 280E 3E;07 LD A,7 ; A must be 0 to 7 2810 A3 AND A,E ; E is the LS byte of the X co-ordinate 2811 6F LD L,A ; L = A = selects bit-mask 2812 26;2D LD H,$2D ; bit-mask array is at $2D00 2814 7E LD A,(HL) ; get byte with bit set at appropriate position 2815 2A;08;23 LD HL,(G007_DISPLAY_ADDRESS) ; Start address of hi-res display file ; ; Add two bytes for every line ; 2818 4A LD C,D ; BC = Y coordinate 2819 06;00 LD B,0 281B 09 ADD HL,BC ; HL += BC*2 281C 09 ADD HL,BC ; ; DE /= 8 gets byte offset from left of screen ; 281D CB;3A SRL D ; shift DE right 281F CB;1B RR E 2821 CB;3A SRL D ; shift DE right 2823 CB;1B RR E 2825 CB;3A SRL D ; shift DE right 2827 CB;1B RR E 2829 19 ADD HL,DE ; HL = G007_DISPLAY_ADDRESS + byte offset of XY-co-ordinates 282A 47 LD B,A ; A and B hold the bitmask 282B C9 RET ; return L282C: 282C 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Plot out of range flags. Bit 7 = latest statement 282F 2A;27;23 LD HL,(G007_PLOT_X_PREVIOUS_N1) 2832 ED;5B;23;23 LD DE,(G007_PLOT_X) ; X co-ordinate for PLOT. Signed 16-bit 2836 D9 EXX 2837 2A;25;23 LD HL,(G007_PLOT_Y) 283A ED;5B;29;23 LD DE,(G007_PLOT_Y_PREVIOUS_N1) 283E CB;77 BIT 6,A 2840 28;1C JR Z,L285E 2842 CB;7F BIT 7,A 2844 C0 RET NZ 2845 3A;21;40 LD A,(UNUSED_8) ; 2848 F5 PUSH AF 2849 06;08 LD B,8 L284B: 284B 0F RRCA 284C FD;CB;21;16 LD C,SLA (IY+22) ; is this a disassembler error? 2850 10;F9 DJNZ L284B 2852 EB EX DE,HL 2853 D9 EXX 2854 EB EX DE,HL 2855 D9 EXX 2856 CD;5E;28 CALL L285E 2859 F1 POP AF 285A 32;21;40 LD (UNUSED_8),A ; 285D C9 RET L285E: 285E 01;DE;FF LD BC,$-34 2861 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) 2864 3D DEC A 2865 93 SUB E 2866 ED;52 SBC HL,DE 2868 F2;76;28 JP P,L2876 286B 01;22;00 LD BC,34 ; bytes per scan line? 286E 7B LD A,E 286F D5 PUSH DE 2870 19 ADD HL,DE 2871 EB EX DE,HL 2872 B7 OR A,A 2873 ED;52 SBC HL,DE 2875 D1 POP DE L2876: 2876 E5 PUSH HL 2877 63 LD H,E 2878 5F LD E,A 2879 D9 EXX 287A 01;FB;28 LD BC,L28FB 287D 7D LD A,L 287E D9 EXX 287F 6F LD L,A 2880 D9 EXX 2881 B7 OR A,A 2882 ED;52 SBC HL,DE 2884 F2;90;28 JP P,L2890 ; [10384] 2887 01;04;29 LD BC,L2904 288A 2F CPL 288B 19 ADD HL,DE 288C EB EX DE,HL 288D B7 OR A,A 288E ED;52 SBC HL,DE L2890: 2890 ED;43;1A;23 LD (G007_TEMP_BYTE_0),BC ; Temporary variables for PLOT routine. 2894 D1 POP DE 2895 B7 OR A,A 2896 ED;52 SBC HL,DE 2898 19 ADD HL,DE 2899 30;09 JR NC,L28A4 289B EB EX DE,HL 289C 01;F6;28 LD BC,L28F6 289F D9 EXX 28A0 53 LD D,E 28A1 5F LD E,A 28A2 7A LD A,D 28A3 D9 EXX 28A4 ED;43;1C;23 LD (G007_TEMP_BYTE_2),BC 28A8 D9 EXX 28A9 57 LD D,A 28AA D5 PUSH DE 28AB D9 EXX 28AC C1 POP BC 28AD 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Plot out of range flags. Bit 7 = latest statement 28B0 FE;40 CP $40 28B2 30;02 JR NC,L28B6 28B4 45 LD B,L ; BC = LE 28B5 4B LD C,E L28B6: 28B6 04 INC B 28B7 0C INC C L28B8: 28B8 CB;3C SRL H 28BA 38;02 JR C,L28BE 28BC 28;08 JR Z,L28C6 L28BE: 28BE CB;1D RR L 28C0 CB;3A SRL D 28C2 CB;1B RR E 28C4 18;F2 JR L28B8 L28C6: 28C6 55 LD D,L 28C7 CB;3D SRL L 28C9 D9 EXX 28CA C5 PUSH BC 28CB CD;07;28 CALL L2807 28CE D1 POP DE 28CF 3A;1F;23 LD A,(G007_TEMP_BYTE_5) 28D2 4F LD C,A 28D3 FD;CB;21;06 LD C,SLA (IY+6) 28D7 38;08 JR C,L28E1 L28D3: 28D9 3A;1E;23 LD A,(G007_TEMP_BYTE_4) 28DC AE XOR A,(HL) 28DD B1 OR A,C 28DE A0 AND A,B 28DF AE XOR A,(HL) 28E0 77 LD (HL),A L28E1: 28E1 D9 EXX 28E2 7D LD A,L 28E3 05 DEC B 28E4 C8 RET Z 28E5 93 SUB E 28E6 30;0A JR NC,L28F2 28E8 0D DEC C 28E9 C8 RET Z 28EA 82 ADD A,D 28EB D9 EXX 28EC 19 ADD HL,DE 28ED D9 EXX 28EE 2A;1A;23 LD HL,(G007_TEMP_BYTE_0) ; Temporary variables for PLOT routine. 28F1 E9 JP (HL) L28F2: 28F2 2A;1C;23 LD HL,(G007_TEMP_BYTE_2) 28F5 E9 JP (HL) L28F6: 28F6 6F LD L,A 28F7 D9 EXX 28F8 19 ADD HL,DE 28F9 18;D8 JR L28D3 L28FB: 28FB 6F LD L,A 28FC D9 EXX 28FD CB;00 RLC B 28FF 30;D2 JR NC,L28D3 2901 2B DEC HL 2902 18;CF JR L28D3 2904 6F LD L,A 2905 D9 EXX 2906 CB;08 RRC B 2908 30;C9 JR NC,L28D3 290A 23 INC HL 290B 18;C6 JR L28D3 L290D: 290D 2A;A8;0E LD HL,($0EA8) ; Inside the 'FIND_INT.' subroutine ; 0EA7 FIND_INT CALL 158A,FP_TO_BC ; so 0EA8 should contain $158A, pointing to the FP_TO_BC routine 2910 E9 JP (HL) ; exit G007_INTEGER_FROM_STACK: 2911 CD;0D;29 CALL L290D ; get an integer 2914 38;0E JR C,L2924 2916 21;00;00 LD HL,$0000 2919 28;06 JR Z,L2921 291B ED;42 SBC HL,BC ; HL = - BC 291D F8 RET M 291E C8 RET Z 291F 18;03 JR L2924 L2921: 2921 ED;4A ADC HL,BC 2923 F0 RET P L2924: 2924 E1 POP HL 2925 C9 RET G007_PLOT_UNPLOT_N_X_Y: ; takes parameters from the stack 2926 CD;11;29 CALL G007_INTEGER_FROM_STACK 2929 22;25;23 LD (G007_PLOT_Y),HL 292C CD;11;29 CALL G007_INTEGER_FROM_STACK 292F E5 PUSH HL 2930 CD;02;0C CALL STK_TO_A 2933 C1 POP BC 2934 ED;5B;25;23 LD DE,(G007_PLOT_Y) 2938 28;0C JR Z,G007_PLOT 293A 3D DEC A 293B C0 RET NZ 293C 21;9C;0C LD HL,L0C9C 293F 22;30;40 LD (T_ADDR),HL ; SET T_ADDR L2942: 2942 43 LD B,E 2943 C3;B2;0B JP $0BB2 ; []*BIOS ROM* ; ; The Plot Routine: ; A == the plot number N ; BC == screen X ; DE == screen Y ; G007_PLOT: 2946 B7 OR A,A 2947 28;F9 JR Z,L2942 2949 3D DEC A ; when PLOT N value is decremented, bits make more sense 294A D5 PUSH DE ; push screen Y 294B C5 PUSH BC ; push screen X 294C F5 PUSH AF ; push plot number-1 294D CD;1F;2E CALL G007_CHECK_AND_SET_UP_DISPLAY_FILE 2950 F1 POP AF 2951 D1 POP DE 2952 C1 POP BC ; NB BC and DE are swapped 2953 FE;81 CP $81 ; Was A=129 (PLOT 130 sets graphics origin) 2955 20;0F JR NZ,G007_PLOT_XY_TO_HISTORY ; G007_ORIGIN_SET: ; 2957 ED;53;30;23 LD (G007_ORIGIN_Y),DE ; Y co-ordinate of graphics origin 295B ED;43;32;23 LD (G007_ORIGIN_X),BC ; X co-ordinate of graphics origin 295F 01;00;00 LD BC,$0000 ; BC = 0 2962 50 LD D,B ; DE = BC = 0 2963 58 LD E,B 2964 3E;0B LD A,$0B ; G007_PLOT_XY_TO_HISTORY: ; 2966 CB;57 BIT 2,A ; 2968 28;09 JR Z,G007_PLOT_ABSOLUTE ; G007_PLOT_RELATIVE: ; 296A 2A;29;23 LD HL,(G007_PLOT_Y_PREVIOUS_N1) 296D E5 PUSH HL 296E 2A;27;23 LD HL,(G007_PLOT_X_PREVIOUS_N1) 2971 18;07 JR G007_PLOT_ABSOLUTE_OR_RELATIVE ; G007_PLOT_ABSOLUTE: ; 2973 2A;32;23 LD HL,(G007_ORIGIN_X) ; X co-ordinate of graphics origin 2976 E5 PUSH HL 2977 2A;30;23 LD HL,(G007_ORIGIN_Y) ; Y co-ordinate of graphics origin ; G007_PLOT_ABSOLUTE_OR_RELATIVE: ; 297A B7 OR A,A 297B ED;5A ADC HL,DE ; HL = Y + G007_ORIGIN_Y 297D D1 POP DE 297E E8 RET PE 297F 22;23;23 LD (G007_PLOT_X),HL ; X co-ordinate for PLOT. Signed 16-bit 2982 EB EX DE,HL 2983 B7 OR A,A 2984 ED;4A ADC HL,BC ; HL = X + G007_ORIGIN_X 2986 E8 RET PE 2987 22;25;23 LD (G007_PLOT_Y),HL 298A 5F LD E,A 298B 3E;C0 LD A,$C0 ; 298D A4 AND A,H ; values 0 to 191 result in zero 298E E0 RET PO ; 298F 3E;C0 LD A,$C0 2991 A2 AND A,D 2992 E0 RET PO 2993 D9 EXX 2994 E5 PUSH HL 2995 D5 PUSH DE 2996 C5 PUSH BC 2997 CD;9F;29 CALL G007_RANGE_CHECK L299A: 299A C1 POP BC 299B D1 POP DE 299C E1 POP HL 299D D9 EXX 299E C9 RET G007_RANGE_CHECK: 299F D9 EXX 29A0 7C LD A,H ; A = H OR D 29A1 B2 OR A,D 29A2 37 SCF 29A3 20;05 JR NZ,G007_RANGE_CHECK_UPDATE ; if not zero, out of range already so ignore display height 29A5 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) ; check Y coordinate 29A8 3D DEC A 29A9 BD CP L G007_RANGE_CHECK_UPDATE: ; latest flag in carry 29AA 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Read 'Plot out of range flags' 29AD 1F RRA ; shift bits right. Bit 7 = latest statement 29AE 32;21;23 LD (G007_OUT_OF_RANGE_FLAGS),A ; Write 'Plot out of range flags' 29B1 7B LD A,E 29B2 CB;7F BIT 7,A 29B4 28;04 JR Z,L29BA 29B6 2A;10;23 LD HL,(G007_PLOT_ROUTINES_VECTOR) ; Vector for additional plot routines 29B9 E9 JP (HL) L29BA: 29BA F5 PUSH AF 29BB E6;03 AND 3 29BD 1F RRA 29BE 3D DEC A 29BF 2F CPL 29C0 67 LD H,A 29C1 9F SBC A,A 29C2 6F LD L,A 29C3 22;1E;23 LD (G007_TEMP_BYTE_4),HL 29C6 E5 PUSH HL 29C7 CB;5B BIT 3,E 29C9 20;28 JR NZ,L29F3 29CB 3A;20;23 LD A,(G007_TEMP_BYTE_6) 29CE AB XOR A,E 29CF E6;FB AND $FB 29D1 28;0F JR Z,L29E2 29D3 21;34;23 LD HL,G007_LINE_TYPE 29D6 7B LD A,E 29D7 07 RLCA ; A *= 8 29D8 07 RLCA 29D9 07 RLCA 29DA E6;03 AND $03 29DC 85 ADD A,L 29DD 6F LD L,A 29DE 7E LD A,(HL) 29DF 32;21;40 LD (UNUSED_8),A ; 29E2 CD;2C;28 CALL L282C ; 29E5 E1 POP HL 29E6 FD;CB;21;0E LD C,SLA (IY+14) 29EA 38;26 JR C,L2A12 29EC 7C LD A,H 29ED A5 AND A,L 29EE 28;22 JR Z,L2A12 29F0 2C INC L 29F1 5D LD E,L 29F2 E5 PUSH HL L29F3: 29F3 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Bit 7 = latest statement 29F6 CB;6B BIT 5,E 29F8 20;3D JR NZ,G007_TRIANGLE_PLAIN 29FA CB;73 BIT 6,E 29FC 20;3E JR NZ,G007_TRIANGLE_TEXTURED 29FE E1 POP HL 29FF CB;7F BIT 7,A 2A01 20;0F JR NZ,L2A12 2A03 E5 PUSH HL 2A04 CD;00;28 CALL G007_GET_PIXEL_ADDRESS_AND_MASK 2A07 A6 AND A,(HL) 2A08 32;17;23 LD (G007_READ_POINT_BYTE),A ; "Read-point" byte. Non-zero if pixel is set. 2A0B D1 POP DE 2A0C 7E LD A,(HL) 2A0D B2 OR A,D 2A0E AB XOR A,E 2A0F A0 AND A,B 2A10 AE XOR A,(HL) 2A11 77 LD (HL),A 2A12 F1 POP AF 2A13 32;20;23 LD (G007_TEMP_BYTE_6),A 2A16 21;2A;23 LD HL,G007_PLOT_Y_PREVIOUS_N1+1 2A19 11;2E;23 LD DE,G007_PLOT_Y_PREVIOUS_N2+1 2A1C 01;08;00 LD BC,8 2A1F CB;67 BIT 4,A 2A21 28;11 JR Z,L2A34 2A23 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Plot out of range flags. Bit 7 = latest statement 2A26 E6;C0 AND $C0 ; only want most recent two bits 2A28 17 RLA 2A29 30;02 JR NC,L2A2D 2A2B CB;F7 SET 6,A ; carry flag into bit 6 of A L2A2D: 2A2D 32;21;23 LD (G007_OUT_OF_RANGE_FLAGS),A 2A30 2E;26 LD L,$26 2A32 0E;04 LD C,4 L2A34: 2A34 ED;B8 LDDR ; (DE--)=(HL--); BC-- UNTIL BC IS ZERO 2A36 C9 RET G007_TRIANGLE_PLAIN: 2A37 21;FF;FF LD HL,$FFFF ; Set all bits in HL 2A3A 18;03 JR G007_TRIANGLE_TEXTURED_BY_HL G007_TRIANGLE_TEXTURED: 2A3C 2A;0A;23 LD HL,(G007_TRIANGLE_TEXTURE) ; Bytes defining triangle texture G007_TRIANGLE_TEXTURED_BY_HL: 2A3F D9 EXX 2A40 E6;E0 AND $E0 ; = 224 2A42 C2;AD;0E JP NZ,REPORT_B ; L2A45: 2A45 21;21;23 LD HL,G007_OUT_OF_RANGE_FLAGS 2A48 FD;36;21;55 LD (IY+33),$55 2A4C 06;03 LD B,3 L2A4E: 2A4E 23 INC HL ; HL+=2 2A4F 23 INC HL 2A50 5E LD E,(HL) 2A51 23 INC HL ; HL+=2 2A52 23 INC HL 2A53 56 LD D,(HL) 2A54 D5 PUSH DE 2A55 10;F7 DJNZ L2A4E ; BC-- ; 2A57 C1 POP BC ; restore register pairs 2A58 D1 POP DE 2A59 E1 POP HL 2A5A B7 OR A,A 2A5B 28;02 JR Z,L2A5F 2A5D 44 LD B,H ; BC=HL 2A5E 4D LD C,L L2A5F: 2A5F 78 LD A,B 2A60 BC CP H 2A61 30;03 JR NC,L2A66 2A63 C5 PUSH BC 2A64 E3 EX (SP),HL 2A65 C1 POP BC L2A66: 2A66 7C LD A,H 2A67 BA CP D 2A68 30;01 JR NC,L2A6B 2A6A EB EX DE,HL L2A6B: 2A6B 7A LD A,D 2A6C D9 EXX 2A6D E6;07 AND 7 2A6F 3C INC A 2A70 47 LD B,A 2A71 7C LD A,H L2A72: 2A72 CB;05 RLC L ; L *= 2 2A74 07 RLCA ; A *= 8 2A75 07 RLCA 2A76 07 RLCA 2A77 10;F9 DJNZ L2A72 ; loop while BC-- is not zero 2A79 67 LD H,A 2A7A 22;38;23 LD (G007_TEMP_BYTE_7),HL ; Temporary variable for PLOT 2A7D D9 EXX 2A7E 7C LD A,H 2A7F B8 CP B 2A80 3E;07 LD A,$07 2A82 30;03 JR NC,L2A87 L2A84: 2A84 C5 PUSH BC 2A85 E3 EX (SP),HL 2A86 C1 POP BC L2A87: 2A87 EB EX DE,HL 2A88 F5 PUSH AF 2A89 79 LD A,C 2A8A D9 EXX 2A8B 67 LD H,A 2A8C 6F LD L,A 2A8D 4F LD C,A 2A8E 22;1A;23 LD (G007_TEMP_BYTE_0),HL ; Temporary variables for PLOT routine. 2A91 06;FE LD B,$FE 2A93 D9 EXX 2A94 93 SUB E 2A95 D9 EXX 2A96 30;04 JR NC,L2A9C 2A98 06;00 LD B,$00 2A9A ED;44 NEG L2A9C: 2A9C 57 LD D,A 2A9D D9 EXX 2A9E 7A LD A,D 2A9F 90 SUB B 2AA0 D9 EXX 2AA1 67 LD H,A 2AA2 BA CP D 2AA3 30;02 JR NC,L2AA7 2AA5 EB EX DE,HL 2AA6 04 INC B L2AA7: 2AA7 6C LD L,H 2AA8 2C INC L 2AA9 5C LD E,H 2AAA CB;3B SRL E L2A9C: 2AAC F1 POP AF 2AAD 0F RRCA 2AAE 30;09 JR NC,L2AB9 2AB0 E5 PUSH HL 2AB1 D5 PUSH DE 2AB2 C5 PUSH BC 2AB3 0F RRCA 2AB4 D9 EXX 2AB5 38;CD JR C,L2A84 2AB7 18;CE JR L2A87 L2AB9: 2AB9 D9 EXX 2ABA 60 LD H,B 2ABB 2E;01 LD L,$01 L2ABD: 2ABD C1 POP BC 2ABE D1 POP DE 2ABF E3 EX (SP),HL L2AC0: 2AC0 2D DEC L 2AC1 20;16 JR NZ,L2AD9 2AC3 2A;1A;23 LD HL,(G007_TEMP_BYTE_0) ; Temporary variables for PLOT routine. 2AC6 79 LD A,C 2AC7 BC CP H 2AC8 38;01 JR C,L2ACB 2ACA 67 LD H,A 2ACB BD CP L 2ACC 30;01 JR NC,L2ACF 2ACE 6F LD L,A L2ACF: 2ACF 22;1A;23 LD (G007_TEMP_BYTE_0),HL ; Temporary variables for PLOT routine. 2AD2 E1 POP HL 2AD3 2D DEC L L2AD4: 2AD4 28;E7 JR Z,L2ABD 2AD6 E5 PUSH HL 2AD7 18;15 JR L2AEE L2AD9: 2AD9 7B LD A,E 2ADA 92 SUB D 2ADB 38;0A JR C,L2AE7 2ADD 5F LD E,A 2ADE CB;40 BIT 0,B 2AE0 28;0C JR Z,L2AEE 2AE2 79 LD A,C 2AE3 80 ADD A,B 2AE4 4F LD C,A 2AE5 18;D9 JR L2AC0 L2AE7: 2AE7 84 ADD A,H 2AE8 5F LD E,A 2AE9 3E;01 LD A,1 2AEB B0 OR A,B 2AEC 81 ADD A,C 2AED 4F LD C,A L2AEE: 2AEE 79 LD A,C 2AEF D9 EXX 2AF0 FD;CB;21;0E LD C,SLA (IY+14) 2AF4 38;CA JR C,L2AC0 2AF6 E3 EX (SP),HL 2AF7 D5 PUSH DE 2AF8 C5 PUSH BC 2AF9 E5 PUSH HL 2AFA ED;5B;1A;23 LD DE,(G007_TEMP_BYTE_0) 2AFE 47 LD B,A 2AFF B9 CP C 2B00 30;02 JR NC,L2B04 2B02 41 LD B,C 2B03 4F LD C,A L2B04: 2B04 ED;43;1A;23 LD (G007_TEMP_BYTE_0),BC 2B08 79 LD A,C 2B09 BB CP E 2B0A 3C INC A 2B0B 38;01 JR C,L2B0E 2B0D 7B LD A,E L2B0E: 2B0E 6F LD L,A 2B0F 7A LD A,D 2B10 B8 CP B 2B11 30;02 JR NC,L2B15 2B13 78 LD A,B 2B14 3D DEC A L2B15: 2B15 95 SUB L 2B16 3C INC A 2B17 F5 PUSH AF 2B18 CD;07;28 CALL L2807 2B1B F1 POP AF 2B1C 4F LD C,A 2B1D EB EX DE,HL 2B1E 21;39;23 LD HL,G007_TEMP_BYTE_8 2B21 7E LD A,(HL) 2B22 07 RLCA 2B23 07 RLCA 2B24 07 RLCA 2B25 77 LD (HL),A 2B26 2B DEC HL 2B27 CB;06 RLC (HL) 2B29 B6 OR A,(HL) 2B2A 2A;1E;23 LD HL,(G007_TEMP_BYTE_4) 2B2D AD XOR A,L 2B2E 2F CPL 2B2F 6F LD L,A 2B30 EB EX DE,HL L2B31: 2B31 7B LD A,E 2B32 AE XOR A,(HL) 2B33 B2 OR A,D 2B34 A0 AND A,B 2B35 AE XOR A,(HL) 2B36 77 LD (HL),A L2B37: 2B37 0D DEC C 2B38 20;14 JR NZ,L2B4E 2B3A E1 POP HL 2B3B 24 INC H 2B3C CB;7D BIT 7,L 2B3E 28;94 JR Z,L2AD4 2B40 E1 POP HL 2B41 E1 POP HL 2B42 E1 POP HL 2B43 E1 POP HL 2B44 7C LD A,H 2B45 A5 AND A,L 2B46 CA;12;2A JP Z,L2A12 2B49 2C INC L 2B4A E5 PUSH HL 2B4B C3;45;2A JP L2A45 L2B4E: 2B4E CB;18 RR B 2B50 30;DF JR NC,L2B31 2B52 23 INC HL 2B53 41 LD B,C 2B54 79 LD A,C 2B55 E6;07 AND $07 2B57 4F LD C,A 2B58 CB;38 SRL B ; B *= 8 2B5A CB;38 SRL B 2B5C CB;38 SRL B 2B5E 28;08 JR Z,L2B68 L2B60: 2B60 7B LD A,E 2B61 AE XOR A,(HL) 2B62 B2 OR A,D 2B63 AE XOR A,(HL) 2B64 77 LD (HL),A 2B65 23 INC HL 2B66 10;F8 DJNZ L2B60 L2B68: 2B68 37 SCF 2B69 0C INC C 2B6A 18;CB JR L2B37 L2B6C: 2B6C 2A;13;23 LD HL,(G007_FLAG_1) 2B6F 2D DEC L 2B70 B5 OR A,L 2B71 C2;09;08 JP NZ,L0809 ; iii) Testing S-POSN: 0808 ENTER-CH LD D,A ; skips that first instruction though. 2B74 25 DEC H 2B75 C2;B8;23 JP NZ,V23B8 ; [9144] 2B78 3A;21;23 LD A,(G007_OUT_OF_RANGE_FLAGS) ; Plot out of range flags. Bit 7 = latest statement 2B7B 17 RLA 2B7C D8 RET C 2B7D 00 NOP 2B7E 00 NOP 2B7F 2A;28;23 LD HL,(G007_PLOT_X_PREVIOUS_N1+1) 2B82 3A;27;23 LD A, (G007_PLOT_X_PREVIOUS_N1) 2B85 CB;72 BIT 6,D 2B87 20;05 JR NZ,L2B8E 2B89 6F LD L,A 2B8A C6;08 ADD A,8 2B8C 30;0D JR NC,L2B9B L2B8E: 2B8E 7C LD A,H 2B8F D6;08 SUB 8 2B91 30;04 JR NC,L2B97 2B93 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) 2B96 3D DEC A 2B97 32;29;23 LD (G007_PLOT_Y_PREVIOUS_N1),A ; 2B9A AF XOR A,A ; A = 0 L2B9B: 2B9B 32;27;23 LD (G007_PLOT_X_PREVIOUS_N1),A 2B9E CB;72 BIT 6,D 2BA0 C0 RET NZ 2BA1 CD;EF;2E CALL L2EEF 2BA4 7D LD A,L 2BA5 FE;F9 CP $F9 2BA7 38;02 JR C,L2BAB 2BA9 1E;02 LD E,2 L2BAB: 2BAB 2F CPL 2BAC E6;07 AND 7 2BAE 3C INC A 2BAF 57 LD D,A 2BB0 7C LD A,H 2BB1 3C INC A 2BB2 D9 EXX 2BB3 57 LD D,A 2BB4 D9 EXX 2BB5 D5 PUSH DE 2BB6 CD;07;28 CALL L2807 2BB9 D9 EXX L2BBA: 2BBA 79 LD A,C 2BBB AE XOR A,(HL) 2BBC D9 EXX 2BBD EB EX DE,HL 2BBE C1 POP BC 2BBF C5 PUSH BC 2BC0 6F LD L,A 2BC1 26;00 LD H,$00 L2BC3: 2BC3 29 ADD HL,HL 2BC4 10;FD DJNZ L2BC3 2BC6 EB EX DE,HL 2BC7 06;02 LD B,2 L2BC9: 2BC9 3A;7B;40 LD A,(UNUSED_16) ; 2BCC AE XOR A,(HL) 2BCD FD;B6;7C OR A,(IY+124) 2BD0 A2 AND A,D 2BD1 AE XOR A,(HL) 2BD2 0D DEC C 2BD3 28;01 JR Z,L2BD6 2BD5 77 LD (HL),A L2BD6: 2BD6 53 LD D,E 2BD7 23 INC HL 2BD8 10;EF DJNZ L2BC9 2BDA 0E;20 LD C,$20 2BDC 09 ADD HL,BC 2BDD D9 EXX 2BDE 23 INC HL 2BDF 15 DEC D 2BE0 28;02 JR Z,L2BE4 2BE2 10;D6 DJNZ L2BBA L2BE4: 2BE4 E1 POP HL 2BE5 C3;9A;29 JP L299A PRINT_007: 2BE8 ED;57 LD A,I ; read graphics mode 2BEA 0F RRCA 2BEB 30;08 JR NC,L2BF5 2BED AF XOR A,A ; A = 0 2BEE 32;22;40 LD (DF_SZ),A ; SET DF_SZ 2BF1 3C INC A 2BF2 32;13;23 LD (G007_FLAG_1),A L2BF5: 2BF5 CD;CF;0A CALL PRINT ; [PRINT] 2BF8 AF XOR A,A ; A = 0 2BF9 32;13;23 LD (G007_FLAG_1),A 2BFC FD;36;22;02 LD (IY+34),$02 ; The lines above have no return or jump statements ; They will fall into copy of the end of the STK_TO_BC routine ; Perhaps a cunning trick to save two bytes? :-) ; ; 256-byte block patched in to ZX81 BASIC at 0C00 hex ; This cleverly alters the language syntax, ; adding parameters and/or pointing to new routines. ; 2C00 4F LD C,A ; from the end of the STK_TO_BC routine 2C01 C9 RET ; THE 'STK_TO_A' SUBROUTINE (duplicated for the paged ROM) ; This subroutine 'loads' the A register with the floating point number held at the top of the calculator stack. The number must be in the range 00-FF. ; STK_TO_A ; 2C02 CD;A0;0C CALL L0CA0 ; ??? This cannot be valid, 0CA0 is in a parameter table ; CALL 15CD,FP_TO_A ; This is what the disassembly book says 2C05 DA;AD;0E JP C,REPORT_B 2C08 0E;01 LD C,$01 2C0A C8 RET Z 2C0B 0E;FF LD C,$FF 2C0D C9 RET ; THE 'SCROLL' COMMAND ROUTINE (duplicated for the paged ROM) ; The first part of the routine sets the correct values of DF_CC and S_POSN to allow for the next printing to occur at the start of the bottom line + 1. ; Next the end address of the first line in the display file is identified and the whole of the display file moved to overwrite this line. ; 2C0E FD;46;22 LD B,(IY+34) ; ??? Disassembly book says LD B,(DF_SZ) 2C11 0E;21 LD C,$21 2C13 CD;18;09 CALL LOC_ADDR 2C16 CD;9B;09 CALL ONE_SPACE 2C19 7E LD A,(HL) 2C1A 12 LD (DE),A 2C1B FD;34;3A INC (IY+58) ; ??? INC (S_POSN_hi.) 2C1E 2A;0C;40 LD HL,(D_FILE) ; 2C21 23 INC HL 2C22 54 LD D,H 2C23 5D LD E,L 2C24 ED;B1 CPIR 2C26 C3;5D;0A JP RECLAIM_1 ; ;0C0E SCROLL LD B,(DF_SZ) ; LD C,+21 ; CALL 0918,LOC._ADDR ; CALL 099B,ONE_SPACE ; LD A,(HL) ; LD (DE),A ; INC (S_POSN_hi.) ; LD HL,(D_FILE) ; INC HL ; LD D,H ; LD E,L ; CPIR ; JP 0A5D,RECLAIM_1 ; ; THE SYNTAX TABLES ; ; i) The offset table ; ; There is an offset value for each of the BASIC commands and by ; adding this offset to the value of the address where it is found, ; the correct address for the command in the parameter table is ; obtained. ; 2C29: 8B 8D 2D 7F 81 49 75 0C29 8B LPRINT 0CB4 0C2A 8D LLIST 0CB1 0C2B 2D STOP 0C58 0C2C 7F SLOW 0CAB 0C2D 81 FAST 0CAE 0C2E 49 NEW 0C77 0C2F 75 SCROLL 0CA4 ; 2C30: 5F 40 42 2B 17 1F 37 52 0C30 5F CONT 0CBF 0C31 40 DIM 0C71 0C32 42 REM 0C74 0C33 2B FOR 0C5E 0C34 17 GOTO 0C4B 0C35 1F GOSUB 0C54 0C36 37 INPUT 0C6D 0C37 52 LOAD 0C89 ; 2C38: 45 0F 6D 2B 44 2D 5A 3B 0C38 45 LIST 0C7D 0C39 0F LET 0C48 0C3A 6D PAUSE 0CA7 0C3B 2B NEXT 0C66 0C3C 44 POKE 0C80 0C3D 2D PRINT 0C6A Same as normal ZX81 0C3E 5A PLOT 0C98 0C3F 3B RUN 0C7A ; 2C40: 4C 45 0D 52 54 4D 15 6A 0C40 4C SAVE 0C8C 0C41 45 RAND 0C86 0C42 0D IF 0C4F 0C43 52 CLS 0C95 0C44 54 UNPLOT 0C98 This byte is 5A, an offset to 0C9E, in normal ZX81 NB same address as PLOT 0C45 4D CLEAR 0C92 0C46 15 RETURN 0C5B 0C47 6A COPY 0CB1 ii) The parameter table. For each of the BASIC commands there are between 3 & 8 entries in the parameter table. The command classes for each of the commands are given, together with the required separators and these are followed by the address of the appropriate routine. ; 2C48: 01 14 02 0C48 P_LET 01 CLASS_1 14 '=' 02 CLASS_2 ; 244B: 06 00 81 0E 06 0C4B P_GOTO 06 CLASS_6 00 CLASS_0 81 0E GOTO,0EB1 ; 2C50: DE 05 AB 0D 0C4F P_IF 06 CLASS_6 DE 'THEN' 05 CLASS_5 AB 0D IF,0DAB ; 2C54: 06 00 B5 0E 0C54 P_GOSUB 06 CLASS_6 00 CLASS_0 B5 0E GOSUB,0EB5 ; 2C58: 00 DC 0C 0C58 P_STOP 00 CLASS_0 DC 0C STOP,0CDC ; 2c5B: 00 D8 0E 0C5B P_RETURN 00 CLASS_0 D8 0E RETURN,0EDB ; 2c5e: 04 14 2C60: 06 DF 06 05 B9 0D 0C5E P_FOR 04 CLASS_4 1A '=' 06 CLASS_6 DF 'TO' 06 CLASS_6 05 CLASS_5 B9 0D FOR,0DB9 ; 0C66: 04 00 2E 0E 0C66 P_NEXT 04 CLASS_4 00 CLASS_0 2E 0E NEXT,0E2E ; 2C6A: 05 E8 2B 0C6A P_PRINT 05 CLASS_5 ; CF 0A PRINT,0ACF This is the original routine E8 2B PRINT_007,2BE8 This is the new routine! ; 2C6D: 01 00 E9 0E 0C6D P_INPUT 01 CLASS_1 00 CLASS_0 E9 0E INPUT,0EE9 ; 2C71: 05 A7 2E 0C71 P_DIM 05 CLASS_5 ; 09 14 DIM,1409 Original ZX81 replaced by A7 2E DIM_007,2EA7 new routine ; 2c74: 05 6A 0D 0C74P_REM 05 CLASS_5 6A 0D REM,0D6A ; 2C77: 00 C3 03 0C77 P_NEW 00 CLASS_0 C3 03 NEW_03C3 ; 2C7A: 03 AF 0E 03 30 07 0C7A P_RUN 03 CLASS_3 AF 0E RUN,0EAF 0C7D P_LIST 03 CLASS_3 30 07 LIST,0730 2C80: 06 1A 06 00 92 0E 03 6C 0E 0C80 P_POKE 06 CLASS_6 1A ',' 06 CLASS_6 92 0E POKE,0E92 0C86 P_RAND 03 CLASS_3 6C 0E RAND,0E6C ; 2C89: 05 40 03 0C89 P_LOAD 05 CLASS_5 40 03 LOAD,0340 ; 2C8C: 05 4D 2F 0C8C P_SAVE 05 CLASS_5 ; F6 02 SAVE,02F6 original 4D 2F SAVE_007,2F4D new! ; 2CBF: 00 7C 0E 0C8F P_CONT 00 CLASS_0 7C 0E CONT,0E7C ; 2C92: 00 B2 0E 0C92 P_CLEAR 00 CLASS_0 ; 9A 14 CLEAR,149A original B2 0E CLEAR,0E B2 new. this points outside the G007 ROM ; 2C95: 03 4E 2E 0C95 P_CLS 00 CLASS_0 ; 2A 0A CLS,0A2A original 4E 2E G007_CLS_N,2E4E new! ; originally the ZX81 does this: ; ; 0C98 P_PLOT 06 CLASS_6 ; 1A ',' ; 06 CLASS_6 ; 00 CLASS_0 ; AF ; 0B PLOT/UNP.,0BAF ; 0C9E P_UNPLOT 06 CLASS_6 ; 1A ',' ; 06 CLASS_6 ; 00 CLASS_0 ; AF ; 0B PLOT/UNP.,0BAF ; ; The G007 saves bytes by having these identical parameter table entries overlapping: ; 2C98: 06 1A 06 1A 06 00 26 29 0C98 P_PLOT 06 CLASS_6 1A ',' 06 CLASS_6 1A ',' 06 CLASS_6 00 CLASS_0 26 29 G007_PLOT_UNPLOT_N_X_Y,2926 new! 2CA0: 2A A8 0E E9 ; 2CA4: 00 0E 0C 0CA4 P_SCROLL 00 CLASS_0 0E 0C SCROLL,0C0E ; 2CA7: 06 00 AE 2E 0CA7 P_PAUSE 06 CLASS_6 00 CLASS_0 ; 32 0F PAUSE,0F32 original AE 2E PAUSE_007,2EAE new! ; 2CAB: 03 B2 2E ; 0CAB P_SLOW 00 CLASS_0 original ; 2B 0F SLOW,0F2B original 0CAB P_SLOW 00 CLASS_3 new! Extra parameter sets graphic mode B2 2E SLOW_007,2EB2 new! ; 2CAE: 03 B6 2E ; 0CAE P_FAST 00 CLASS_0 original ; 23 0F FAST,0F23 original 0CAE P_FAST 03 CLASS_3 new! Extra parameter sets graphic mode B6 2E FAST_007,2EB6 new! ; 2CB1: 03 53 2F ; 0CB1 P_COPY 00 CLASS_0 ; 69 ; 08 COPY,0869 original ; 53 2F COPY_007,2EB6 new! 0CB1 P_COPY 03 CLASS_3 new! Extra parameter sets graphic mode 53 2F COPY_007,2EB6 new! ; 2CB4: 05 CB 0A 0CB4 P_LPRINT 05 CLASS_5 CB 0A LPRINT,0ACB ; 2CB7: 03 2C 07 0CB7 P_LLIST 03 CLASS_3 2C 07 LLIST,072C ; the rest of this page is just a copy of the usual ZX81 code ; 2CBA: FD 36 01 01 CD 73 ; 2CC0: 0A CD 95 0A 21 00 40 36 ; 2CC8: FF 21 2D 40 CB 6E 28 0E ; 2CD0: FE E3 7E C2 6F 0D CD A6 ; 2CD8: 0D C8 CF 0C CF 08 DF 06 ; 2CE0: 00 FE 76 C8 4F E7 79 D6 ; 2CE8: E1 38 3B 4F 21 29 0C 09 ; 2CF0: 4E 09 18 03 2A 30 40 7E ; 2CF8: 23 22 30 40 01 F4 0C C5 ; which is described as follows in the ZX81 disassembly book: ; THE 'LINE SCANNING' ROUTINE ; The BASIC interpreter scans each line for BASIC commands and as each one is found the appropriate command routine is followed. ; The different parts of the routine are: i) The LINE_SCAN entry point leads to the line number being checked for validity. 0CBA LINE_SCAN LD (FLAGS),+01 CALL 0A73,E_LINE_NO ; ii) The LINE_RUN entry point is used when replying to an INPUT prompt and this fact has be identified. 0CC1 LINE_RUN CALL 14BC,SET_MEM LD HL,+ERR_NR LD (HL),+FF LD HL,+FLAGX BIT 5,(HL) JR Z,0CDE,LINE_NULL ; iii) The INPUT reply is tested to see if STOP was entered. CP +E3 LD A,(HL) JP NZ,0D6F,INPUT_RE CALL 0DA6,SYNTAX_2 RET Z ; iv) If appropriate, report D is given. RST 0008,ERROR_1 DEFB +0C ; THE 'STOP' COMMAND ROUTINE ; The only action is to give report 9. 0CDC STOP RST 0008,ERROR_1 DEFB +08 ; v) A return is made if the line is 'null'. 0CDE LINE_NULL RST 0018,GET_CH. LD B,+00 CP +76 RET Z ; vi) The first character is tested so as to check that it is a command. LD C,A RST 0020,NEXT_CH. LD A,C SUB +E1 JR C,0D26,REPORT_C ; vii) The offset for the command is found from the offset table. LD C,A LD HL,+0C29 ADD HL,BC LD C,(HL) ADD HL,BC JR 0CF7,GET_PARAM ; viii) The parameters are fetched in turn by a loc that returns to 0CF4. The separators are identitied by the test against +0B. 0CF4 SCAN_LOOP LD HL,(T_ADDR) 0CF7 GET_PARAM LD A,(HL) INC HL LD (T_ADDR),HL LD BC,+0CF4 PUSH BC ; ; This is what the VB81 disassembler produced: 2CB9 07 RLCA 2CBA FD;36;01;01 LD (IY+1),$01 2CBE CD;73;0A CALL L0A73 ; [E_LINE_NO] 2CC1 CD;95;0A CALL L0A95 ; []*BIOS ROM*. Part way into 088A COPY-CONT 2CC4 21;00;40 LD HL,L4000 2CC7 36;FF LD (HL),$FF 2CC9 21;2D;40 LD HL,L402D 2CCC CB;6E BIT 5,(HL) 2CCE 28;0E JR Z,L2CDE 2CD0 FE;E3 CP $E3 2CD2 7E LD A,(HL) 2CD3 C2;6F;0D JP NZ,L0D6F ; [INPUT_REP] 2CD6 CD;A6;0D CALL L0DA6 ; [SYNTAX_Z] 2CD9 C8 RET Z 2CDA CF RST 08 2CDB 0C 0C ; RST8 Arg ; Error Code:'D' 2CDC CF RST 08 2CDD 08 08 ; RST8 Arg ; Error Code:'9' 2CDE DF RST 18 2CDF 06;00 LD B,$00 2CE1 FE;76 CP $76 2CE3 C8 RET Z 2CE4 4F LD C,A 2CE5 E7 RST 20 2CE6 79 LD A,C 2CE7 D6;E1 SUB $E1 2CE9 38;3B JR C,L2D26 2CEB 4F LD C,A 2CEC 21;29;0C LD HL,$0C29 2CEF 09 ADD HL,BC 2CF0 4E LD C,(HL) 2CF1 09 ADD HL,BC 2CF2 18;03 JR L2CF7 2CF4 2A;30;40 LD HL,(T_ADDR) ; GET T_ADDR 2CF7 7E LD A,(HL) 2CF8 23 INC HL 2CF9 22;30;40 LD (T_ADDR),HL ; SET T_ADDR 2CFC 01;F4;0C LD BC,L0CF4 2CFF C5 PUSH BC ; there is more to this routine but the patch ends ; end of patch ; bits shifting right within a byte: ; 2D00 80 DEFB $80 ; 10000000 2D00 40 DEFB $40 ; 01000000 2D00 20 DEFB $20 ; 00100000 2D00 10 DEFB $10 ; 00010000 2D00 08 DEFB $08 ; 00001000 2D00 04 DEFB $04 ; 00000100 2D00 02 DEFB $02 ; 00000010 2D00 01 DEFB $01 ; 00000001 L2D08: 2D08 CD;F7;2B CALL L2BF7 ; ??? not a valid opcode address? 2D0B C3;07;02 JP SLOW_FAST 2D0E 32;28;40 LD (MARGIN),A ; SET MARGIN 2D11 EB EX DE,HL 2D12 21;0A;00 LD HL,$000A 2D15 39 ADD HL,SP 2D16 7E LD A,(HL) 2D17 3C INC A 2D18 E6;F0 AND $F0 2D1A D6;D0 SUB $D0 2D1C 4F LD C,A 2D1D 23 INC HL 2D1E 7E LD A,(HL) 2D1F D6;04 SUB $04 2D21 B1 OR A,C 2D22 4F LD C,A 2D23 3A;3B;40 LD A,(CDFLAG) ; GET CDFLAG 2D26 07 RLCA 2D27 9F SBC A,A 2D28 A1 AND A,C 2D29 20;10 JR NZ,L2D3B 2D2B 2A;10;40 LD HL,($4010) ; GET VARS 2D2E 01;DF;FF LD BC,$FFDF 2D31 09 ADD HL,BC 2D32 CB;FC SET 7,H 2D34 22;04;23 LD (G007_DISPLAY_LO_RES_LAST_LINE_ADDRESS),HL ; Start address of last line of lo-res display file 2D37 3E;01 LD A,$01 2D39 18;0E JR L2D49 L2D3B: 2D3B 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2D3E ED;4B;00;23 LD BC,(G007_DISPLAY_OFFSET_FROM_DFILE_LESS_9) ; Offset of hi-res display file, less 9, from the D_FILE variable 2D42 09 ADD HL,BC 2D43 CB;FC SET 7,H 2D45 22;06;23 LD (G007_DISPLAY_ADDRESS_LESS_9),HL 2D48 AF XOR A,A ; A = 0 2D49 32;19;23 LD (G007_FLAGS),A ; $2319 2D4C 2B DEC HL 2D4D 7E LD A,(HL) 2D4E EB EX DE,HL 2D4F C9 RET 2D50 3A;19;23 LD A,(G007_FLAGS) ; $2319 2D53 3D DEC A 2D54 C2;73;2D JP NZ,L2D73 ; [11635] 2D57 3E;1E LD A,G007_INT_REG_VALUE_FOR_LO_RES_GRAPHICS 2D59 ED;47 LD I,A ; Interrupt register = 0x1E sets low res mode 2D5B ED;6A ADC HL,HL 2D5D 2A;04;23 LD HL,(G007_DISPLAY_LO_RES_LAST_LINE_ADDRESS) ; Start address of last line of lo-res display file 2D60 01;08;01 LD BC,L0108 2D63 3E;FE LD A,$FE 2D65 CD;B5;02 CALL DISPLAY_5 ; 2D68 3E;1F LD A,G007_INT_REG_VALUE_FOR_HI_RES_GRAPHICS 2D6A ED;47 LD I,A ; Interrupt register = 0x1F sets high res mode 2D6C 3A;28;40 LD A,(MARGIN) ; GET MARGIN 2D6F D6;08 SUB 8 2D71 18;04 JR L2D77 2D73 2B DEC HL 2D74 3A;28;40 LD A,(MARGIN) ; GET MARGIN L2D77: 2D77 4F LD C,A 2D78 DD;E1 POP IX 2D7A FD;CB;3B;7E LD E,SRL (IY+126) 2D7E C2;9D;02 JP NZ,L029D ; []*BIOS ROM* ; This jumps into the middle of the DISPLAY_3, where it meets this code: ;029D 79 LD A,C ;029E ED;44 NEG ;02A0 3C INC A ;02A1 08 EX AF,AF' ;02A2 D3;FE OUT ($FE),A ; ZX81 NMI GENERATOR on, for SLOW mode ;02A4 E1 POP HL ; restore registers ;02A5 D1 POP DE ;02A6 C1 POP BC ;02A7 F1 POP AF ;02A8 C9 RET 2D81 3E;FE LD A,$FE 2D83 06;01 LD B,$01 2D85 21;9A;2D LD HL,L2D9A 2D88 CD;95;2D CALL L2D95 ; [11669] 2D8B 29 ADD HL,HL 2D8C 00 NOP 2D8D 5F LD E,A 2D8E 2A;06;23 LD HL,(G007_DISPLAY_ADDRESS_LESS_9) 2D91 CB;FC SET 7,H 2D93 DD;E9 JP (IX) L2D95: 2D95 ED;4F LD R,A 2D97 3E;DD LD A,$DD 2D99 FB EI L2D9A: 2D9A 76 HALT ; ; Copy two pages of ZX81 BASIC ROM to RAM patch areas, ; then modify bytes as controlled by a table of offsets and values ; This uses less memory than two whole pages of ROM ; If the RAM patches are not changed thereafter, ; one might be able to use a 16K ROM to hold two different versions of the ZX81 BASIC space, ; one with the 'RAM' patch and one without. ; The RAM testing would have to be disabled, because the ROM would cause it to fail. ; G007_COPY: ; ; First check RAM by loading 512 bytes RAM from $2200 to $23FF with value 1, and decrement them to zero to test they are working RAM ; 2D9B 21;00;22 LD HL,V2200 ; destination RAM patch 2 2D9E 3E;24 LD A,$24 L2DA0: 2DA0 36;01 LD (HL),$01 ; try writing the value 1 to a byte in RAM patch 2 2DA2 35 DEC (HL) ; try decrementing it to zero 2DA3 28;02 JR Z,L2DA7 ; if result is zero, skip error code report 2DA5 CF RST 08 2DA6 1A 1A ; RST8 Arg ; Error Code:'R' (ZX81 on-board 1K/2K RAM not found) L2DA7: 2DA7 23 INC HL ; next address 2DA8 BC CP H ; has HL reached $2400 (yet? 2DA9 20;F5 JR NZ,L2DA0 ; no, repeat. ; HL is now $2400 ; Copy 256 bytes from BASIC ROM to RAM patch 1: 2DAB 65 LD H,L ; HL is now $0000 (data source is start of ZX81 BASIC ROM) 2DAC 11;00;20 LD DE,L2000 ; data destination is RAM patch 1 2DAF 01;00;01 LD BC,$0100 ; 256 bytes 2DB2 ED;B0 LDIR ; (HL) -> (DE) 256 times ; HL is now $0100 ; DE is now $2100 ; BC is now $0000 2DB4 24 INC H ; HL is now $0200 2DB5 14 INC D ; DE is now $2200 2DB6 04 INC B ; BC is now $0100 2DB7 ED;B0 LDIR ; copy another 256 bytes to RAM patch 2 ; ; ; 2DB9 21;F1;07 LD HL,PRINT_CH ; src = the original ZX81 print character routine 2DBC 11;A0;23 LD DE,V23A0 ; dst = 2DBF 01;60;00 LD BC,$0060 ; 60hex = 96 bytes, so stops just before 0851 (the 'LPRINT-CH routine) 2DC2 ED;B0 LDIR ; move ; BC is now $0000 2DC4 16;20 LD D,$20 ; DE is now $20?? 2DC6 21;B4;2F LD HL,TABLE_ONE ; copy data from this table: L2DC9: 2DC9 46 LD B,(HL) ; BC is now $0A00 (seems way too many bytes) 2DCA 18;04 JR L2DD0 ; branch to end-of-table test G007_TABLE_ONE_LOOP: 2DCC 5E LD E,(HL) ; Get the offset 2DCD 23 INC HL ; next byte is data 2DCE 7E LD A,(HL) ; Get the data byte 2DCF 12 LD (DE),A ; ($2000+offset) = data byte L2DD0: 2DD0 23 INC HL ; next offset 2DD1 10;F9 DJNZ G007_TABLE_ONE_LOOP ; repeat until BC is zero 2DD3 14 INC D ; D becomes $21 2DD4 CB;52 BIT 2,D ; test bit 2 (has D incremented to $23 ?) 2DD6 28;F1 JR Z,L2DC9 2DD8 C9 RET ; ; Delete Display File: ; G007_DELETE_DISPLAY_FILE: 2DD9 CD;E7;02 CALL SET_FAST ; 2DDC 21;87;3E LD HL,$3E87 2DDF CD;D8;09 CALL LINE_ADDR ; 2DE2 C0 RET NZ 2DE3 EB EX DE,HL 2DE4 2A;29;40 LD HL,(NXT_LINE) ; GET NXT_LINE 2DE7 CB;76 BIT 6,(HL) 2DE9 28;04 JR Z,L2DEF 2DEB ED;53;29;40 LD (NXT_LINE),DE ; SET NXT_LINE L2DEF: 2DEF 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2DF2 C3;5D;0A JP RECLAIM_1 ; exit L2DF5: 2DF5 CD;D9;2D CALL G007_DELETE_DISPLAY_FILE 2DF8 01;92;19 LD BC,$1992 ; 6546 decimal = 2DFB 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2DFE 2B DEC HL 2DFF CD;9E;09 CALL MAKE_ROOM 2E02 3E;76 LD A,$76 ; HALT opcode 2E04 12 LD (DE),A ; to DE 2E05 13 INC DE 2E06 12 LD (DE),A ; and DE+1 2E07 23 INC HL ; HL += 2 2E08 23 INC HL 2E09 36;3E LD (HL),$3E ; (HL++) = $3E 'Y' 2E0B 23 INC HL 2E0C 36;87 LD (HL),$87 ; (HL++) = $87 2E0E 23 INC HL 2E0F 36;8D LD (HL),$8D ; (HL++) = $8D 2E11 23 INC HL 2E12 36;19 LD (HL),$19 ; (HL++) = $19 ';' 2E14 23 INC HL 2E15 77 LD (HL),A ; (HL++) = $76 HALT 2E16 23 INC HL 2E17 77 LD (HL),A ; (HL++) = $76 HALT 2E18 CD;07;02 CALL SLOW_FAST ; low-res! 2E1B 3E;01 LD A,1 2E1D 18;37 JR G007_CLS_HI_RES ; G007_CHECK_AND_SET_UP_DISPLAY_FILE: ; 2E1F 2A;65;22 LD HL,(V2265) ; in the RAM page 2 area ! Usually $4027 2E22 11;D9;BF LD DE,$BFD9 ; 3FD9 + 32K, or -16423 = 16K - 39 bytes 2E25 19 ADD HL,DE 2E26 3A;64;22 LD A,(V2264) 2E29 D6;21 SUB $21 2E2B B4 OR A,H 2E2C B5 OR A,L 2E2D C4;9B;2D CALL NZ,G007_COPY 2E30 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2E33 3E;76 LD A,$76 ; HALT character 2E35 2B DEC HL 2E36 2B DEC HL 2E37 BE CP (HL) ; point to a HALT? 2E38 C4;F5;2D CALL NZ,L2DF5 ; no, ; else yes 2E3B 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2E3E ED;5B;00;23 LD DE,(G007_DISPLAY_OFFSET_FROM_DFILE_LESS_9) ; Offset of hi-res display file, less 9, from the D_FILE variable 2E42 19 ADD HL,DE 2E43 22;06;23 LD (G007_DISPLAY_ADDRESS_LESS_9),HL 2E46 11;09;00 LD DE,$0009 2E49 19 ADD HL,DE 2E4A 22;08;23 LD (G007_DISPLAY_ADDRESS),HL ; Start address of hi-res display file = HL 2E4D C9 RET ; G007_CLS_N: ; 2E4E CD;02;0C CALL STK_TO_A 2E51 C0 RET NZ ; drop through if zero flag set ; ; Clear The Screen: ; G007_CLS_A: 2E52 3D DEC A 2E53 FA;2A;0A JP M,$0A2A ; [CLS] if A was zero G007_CLS_HI_RES: 2E56 F5 PUSH AF 2E57 CD;1F;2E CALL G007_CHECK_AND_SET_UP_DISPLAY_FILE 2E5A F1 POP AF 2E5B FE;02 CP 2 2E5D ED;4B;18;23 LD BC,(G007_DISPLAY_HEIGHT) 2E61 2A;0C;40 LD HL,(D_FILE) ; GET D_FILE 2E64 30;30 JR NC,L2E96 2E66 3D DEC A 2E67 23 INC HL 2E68 22;0E;40 LD (DF_CC),HL ; SET DF_CC 2E6B 2B DEC HL 2E6C 2B DEC HL 2E6D 2B DEC HL 2E6E 1E;00 LD E,$00 L2E70: 2E70 06;10 LD B,$10 2E72 2B DEC HL 2E73 73 LD (HL),E 2E74 2B DEC HL 2E75 73 LD (HL),E L2E76: 2E76 2B DEC HL 2E77 77 LD (HL),A 2E78 2B DEC HL 2E79 77 LD (HL),A 2E7A 10;FA DJNZ L2E76 2E7C 0D DEC C 2E7D 20;F1 JR NZ,L2E70 2E7F 06;09 LD B,$09 2E81 3E;01 LD A,$01 L2E83: 2E83 2B DEC HL 2E84 73 LD (HL),E 2E85 10;FC DJNZ L2E83 2E87 21;34;23 LD HL,G007_LINE_TYPE 2E8A 06;14 LD B,$14 2E8C 3D DEC A 2E8D 28;F4 JR Z,L2E83 2E8F 21;21;18 LD HL,$1821 2E92 22;39;40 LD (S_POSN),HL ; SET S_POSN 2E95 C9 RET L2E96: 2E96 C0 RET NZ 2E97 2B DEC HL 2E98 2B DEC HL 2E99 06;20 LD B,$20 2E9B 2B DEC HL 2E9C 2B DEC HL 2E9D 2B DEC HL 2E9E 7E LD A,(HL) 2E9F 2F CPL 2EA0 77 LD (HL),A 2EA1 10;FA DJNZ L2E9D 2EA3 0D DEC C 2EA4 20;F3 JR NZ,L2E99 2EA6 C9 RET DIM_007: ; 2EA7 2EA7 2A;96;0A LD HL,($0A96) 2EAA 3E;4D LD A,$4D 2EAC 18;35 JR L2EE3 2EAE 3E;DD LD A,$DD 2EB0 18;2E JR L2EE0 SLOW_007: ; 2EB2 2EB2 3E;D6 LD A,$D6 2EB4 18;02 JR L2EB8 FAST_007 ; 2EB6 2EB6 3E;CE LD A,$CE 2EB8 F5 PUSH AF 2EB9 CD;02;0C CALL STK_TO_A 2EBC 06;1E LD B,$1E 2EBE 3D DEC A 2EBF FE;06 CP 6 2EC1 30;19 JR NC,L2EDC 2EC3 CB;3F SRL A 2EC5 67 LD H,A 2EC6 28;02 JR Z,L2ECA 2EC8 3E;01 LD A,1 2ECA F5 PUSH AF 2ECB 9F SBC A,A 2ECC 6F LD L,A 2ECD CB;8C RES 1,H 2ECF 25 DEC H 2ED0 22;7B;40 LD (UNUSED_16),HL 2ED3 CD;1F;2E CALL G007_CHECK_AND_SET_UP_DISPLAY_FILE 2ED6 06;1F LD B,G007_INT_REG_VALUE_FOR_HI_RES_GRAPHICS 2ED8 F1 POP AF 2ED9 32;14;23 LD (G007_FLAG_2),A 2EDC 78 LD A,B ; 2EDD ED;47 LD I,A ; I = B = G007_INT_REG_VALUE_FOR_HI_RES_GRAPHICS = set video mode 2EDF F1 POP AF 2EE0 2A;71;0D LD HL,($0D71) ; inside the 'COMMAND CLASS 2' routine of the ZX BASIC ROM 2EE3 85 ADD A,L 2EE4 6F LD L,A 2EE5 E9 JP (HL) 2EE6 57 LD D,A 2EE7 3A;39;40 LD A,(S_POSN) ; GET S_POSN 2EEA E6;80 AND $80 2EEC C3;6C;2B JP L2B6C L2EEF: 2EEF 7A LD A,D 2EF0 D1 POP DE 2EF1 D9 EXX 2EF2 E5 PUSH HL 2EF3 D5 PUSH DE 2EF4 C5 PUSH BC 2EF5 2A;0C;23 LD HL,(G007_CHAR_TABLE_ADDR_0_63) ; Character table address for CHR$0-63 2EF8 87 ADD A,A 2EF9 30;0B JR NC,L2F06 2EFB 2A;0E;23 LD HL,(G007_CHAR_TABLE_ADDR_128_159) ; Character table address for CHR$128-159 2EFE CB;77 BIT 6,A 2F00 28;04 JR Z,L2F06 2F02 2A;15;23 LD HL,(G007_USR_DEF_CHR_TAB_LESS_256) ; Address of user-defined character table, less 256 2F05 3F CCF L2F06: 2F06 EB EX DE,HL 2F07 6F LD L,A 2F08 26;00 LD H,0 2F0A 9F SBC A,A 2F0B 4F LD C,A 2F0C 3A;7B;40 LD A,(UNUSED_16) 2F0F 2F CPL 2F10 FD;A6;7C AND A,(IY+124) 2F13 A9 XOR A,C 2F14 4F LD C,A 2F15 29 ADD HL,HL 2F16 29 ADD HL,HL 2F17 19 ADD HL,DE 2F18 06;08 LD B,8 2F1A D9 EXX 2F1B D5 PUSH DE 2F1C C9 RET L2F1D: ; The copied and modified PRINT_CH / WRITE_CH jumps here from $23FF 2F1D FD;35;39 DEC (IY+57) 2F20 3E;18 LD A,24 ; 24 character rows per screen 2F22 90 SUB B 2F23 47 LD B,A 2F24 87 ADD A,A 2F25 87 ADD A,A 2F26 87 ADD A,A 2F27 6F LD L,A 2F28 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) 2F2B 95 SUB L 2F2C D8 RET C 2F2D 3E;21 LD A,$21 2F2F 91 SUB C 2F30 4F LD C,A 2F31 26;00 LD H,$00 2F33 29 ADD HL,HL 2F34 09 ADD HL,BC 2F35 ED;4B;08;23 LD BC,(G007_DISPLAY_ADDRESS) 2F39 09 ADD HL,BC 2F3A CD;EF;2E CALL L2EEF 2F3D 01;22;00 LD BC,$0022 2F40 D9 EXX 2F41 79 LD A,C 2F42 AE XOR A,(HL) 2F43 D9 EXX 2F44 77 LD (HL),A 2F45 09 ADD HL,BC 2F46 D9 EXX 2F47 23 INC HL 2F48 10;F7 DJNZ L2F41 2F4A C3;9A;29 JP L299A SAVE_007: ; 2F4D 2F4D CD;D9;2D CALL G007_DELETE_DISPLAY_FILE 2F50 C3;F6;02 JP SAVE 2F53 CD;02;0C CALL STK_TO_A 2F56 C0 RET NZ 2F57 3D DEC A 2F58 FA;69;08 JP M,COPY 2F5B CD;1F;2E CALL G007_CHECK_AND_SET_UP_DISPLAY_FILE 2F5E CD;E7;02 CALL SET_FAST 2F61 3A;18;23 LD A,(G007_DISPLAY_HEIGHT) 2F64 47 LD B,A 2F65 2A;08;23 LD HL,(G007_DISPLAY_ADDRESS) 2F68 AF XOR A,A ; A = 0 2F69 5F LD E,A ; E = 0 2F6A D3;FB OUT (ZX_PRINTER_PORT),A L2F6C: 2F6C 3E;7F LD A,$7F 2F6E DB;FE IN A,(ZX_KEYBOARD_PORT) 2F70 0F RRCA 2F71 D2;86;08 JP NC,$0886 ; []*BIOS ROM* between 0880 COPY-BRK and 0888 REPORT-D2 2F74 DB;FB IN A,(ZX_PRINTER_PORT) L2F76: 2F76 87 ADD A,A 2F77 FA;AD;2F JP M,L2FAD 2F7A 30;F0 JR NC,L2F6C 2F7C 0E;20 LD C,$20 ; 32 L2F7E: 2F7E C5 PUSH BC 2F7F 4E LD C,(HL) 2F80 06;08 LD B,8 2F82 CB;01 RLC C 2F84 1F RRA 2F85 B3 OR A,E 2F86 57 LD D,A L2F87: 2F87 DB;FB IN A,(ZX_PRINTER_PORT) 2F89 1F RRA 2F8A 30;FB JR NC,L2F87 2F8C 7A LD A,D 2F8D D3;FB OUT (ZX_PRINTER_PORT),A 2F8F 10;F1 DJNZ L2F82 2F91 23 INC HL 2F92 C1 POP BC 2F93 0D DEC C 2F94 20;E8 JR NZ,L2F7E 2F96 23 INC HL 2F97 23 INC HL 2F98 3E;03 LD A,$03 2F9A B8 CP B 2F9B 38;02 JR C,L2F9F 2F9D 5F LD E,A 2F9E 1D DEC E L2F9F: 2F9F DB;FB IN A,(ZX_PRINTER_PORT) 2FA1 1F RRA 2FA2 30;FB JR NC,L2F9F 2FA4 7B LD A,E 2FA5 D3;FB OUT (ZX_PRINTER_PORT),A 2FA7 10;C3 DJNZ L2F6C 2FA9 3E;04 LD A,4 2FAB D3;FB OUT (ZX_PRINTER_PORT),A L2FAD: 2FAD C3;07;02 JP SLOW_FAST 2FB0 FB EI 2FB1 10;C3 DJNZ L2F76 2FB3 3E DEFB $3E ; TABLE_ONE: ; ; this table is copied to offsets from $2000, $2200, and $2300 ; 2FB4 0A ; Modify 9 bytes in page 20xx / 00xx: ; ; Original routine Modifications made in page 00xx ; ; 0011 C2 F1 07 JP NZ,$07F1 ; [PRINT_CH] ; 2011 C2 A0 23 JP NZ,$23A0 ; checked :-) 2FB5 12 A0 ; 0011 C2;F1;07 JP NZ,PRINT_CH ; old 2FB7 13 23 ; 0011 C2;A0;23 JP NZ,L23A0 ; new, jump somewhere in RAM ??? ; 0014 C3 F5 07 JP $07F5 ; [PRINT-SP] ; 2014 C3 A4 23 JP $23A4 2FB9 15 A4 ; 0014 C3;F5;07 JP PRINT_SP 2FBB 16 23 ; 0014 C3;A4;23 JP L23A4 ; new, jumps to somewhere in RAM ; 003F CB D9 SET 3,C ; 203F CB C1 SET 0,C ; 003F CB;D9 SET 3,C ; old 2FBD 40 C1 ; 003F CB;C1 SET 0,C ; new ; 005F CD 07 02 CALL $0207 ; [SLOW/FAST] ; 205F CD 08 2D CALL $2D08 2FBF 60 08 ; 005F CD;07;02 CALL SLOW_FAST ; old 2FC1 61 2D ; 005F CD;08;2D CALL L2D08 ; new ; 0074 2A 0C 40 LD HL,($400C) ; GET D-FILE ; 2074 2A 06 23 LD HL,($2306) 2FC3 75 06 ; 0074 2A;0C;40 LD HL,(D_FILE) 2FC5 76 23 ; 0074 2A;06:23 LD HL,(G007_DISPLAY_FILE_LESS_9) ; new 2FC7 01 2FC8 0A ; Modify 9 bytes in page 22xx / 02xx: ; ; Original routine Modifications made in page 02xx ; ; 0253 06 0B LD B,$0B 2253 06 02 LD B,$02 2FC9 54 02 ; 0054 02 ; 0283 01 01 19 LD BC,$1901 2283 01 01 C1 LD BC,$C101 2FCB 85 C1 ; ; 027E CD 92 02 CALL $0292 ; [DISPLAY-3] 227E CD 73 2D CALL $2D73 2FCD 7F 73 ; 2FCF 80 2D ; ; 028C CD 92 02 CALL $0292 ; [DISPLAY-3] 228C CD 50 2D CALL $2D50 2FD1 8D 50 ; 2FD3 8E 2D ; ; 02E3 32 28 40 LD ($4028),A ; SET MARGIN 22E3 C3 0E 2D JP $2D0E 2FD5 E3 C3 ; 2FD7 E4 0E ; 2FD9 E5 2D ; ; ; Original routine Modifications made to the copy of the PRINT-CH routines: ; ; ; Variables in the sparsely populated G007 RAM areas 2FDB 13 ; Initialise 18 (decimal, = 12 in hex)RAM variables at $23xx: 2FDC 00 75 ; 2300 75 2FDE 01 E6 ; 2301 E6 2FE0 E6 0A ; 23E6 0A 2FE2 55 0D ; 2355 0D 2FE4 1E 0F ; 231E 0F 2FE6 16 20 ; 2316 20 2FE8 10 07 ; 2310 07 2FEA 11 08 ; 2311 08 2FEC 18 C0 ; 2318 C0 2FEE 35 EE ; 2335 EE 2FF0 36 55 ; 2336 55 2FF2 37 C6 ; 2337 C6 ; The values below were seen in RAM but are not initialised from this table: ; ; 2306 84 4084 G007_DISPLAY_FILE_LESS_9 ; 2307 40 ; 2308 8D 408D G007_DISPLAY_ADDRESS ; 2309 40 ; 230A 55 00 55,00 G007_TRIANGLE_TEXTURE ; 230C 00 1E00 Character table address for CHR$0-63 ; 230D 1E ; 230E 00 1E00 Character table address for CHR$128-159 ; 230F 1E ; ; Modding offsets in code ; ; 07FD CD 08 08 CALL $0808 ; [ENTER-CH] ; 23AC CD E6 2E CALL $2EE6 2FF4 AD E6 2FF6 AE 2E ; 0843 FD 35 39 DEC (IY+57) ; 23F2 C3 1D 2F JP $2F1D 2FF8 F2 C3 2FF9 F3 1D 2FFB F4 2F ; 083E 77 LD (HL),A ; WRITE-CH 23ED 00 NOP ; WRITE-CH modified! 2FFE ED 00