00000000 1 ;MONITOR.S 00000000 2 ;Z8000 assembler source file (Zilog syntax) 00000000 3 ; 00000000 4 ;******************************************************************************** 00000000 5 ;* Adapted and documented version of Rolf-Dieter Klein's z8000 (z8002) Monitor * 00000000 6 ;* originally published in: * 00000000 7 ;* Basic-Interpreter; Funktionsweise und Implementierung in 8080/z80-Computern, * 00000000 8 ;* ISBN 3-7723-6942-1 (2nd edition, 1982) * 00000000 9 ;******************************************************************************** 00000000 10 ; 00000000 11 ;Run at DOS command line: Z8000.BAT MONITOR 00000000 12 ;Author: Jurjen Kranenborg, okt. 2003 (www.kranenborg.org) 00000000 13 ;Note 1: ZASM syntax slightly different from PLZ/ASM 00000000 14 ;Note 2: Code developed for Z8001 CPU 00000000 15 00000000 16 00000000 17 ;################################################################################ 00000000 18 ;# ZASM Assembly starts HERE # 00000000 19 ;################################################################################ 00000000 20 00000000 21 ;Assembler: Definition of main constants 00000000 22 CONSTANT ; NOTE: this keyword MUST be non-indented! 00000000 23 00000000 24 00000000 25 ;================================================================================ 00000000 26 ;Startup; PSA Area; initialization of z8001 00000000 27 ;Note: all handlers will start in segmented mode (because the handlers are assumed to leave 00000000 28 ; with IRET which requires segmented mode) except for the start vector (PSA_reset) 00000000 29 ; because this is a jump. 00000000 30 00000000 31 PSA_AREA: ; PSA_Area starts at <0>,0000 (=Addr_PSA), for z8001 always in segmented format 00000000 32 00000000 33 PSA_reset: ; Reset area 00000000 0000 34 .word %0000 ; 1st: unused 00000002 4000 35 .word %4000 ; 2nd: FCW set: Nonsegmented, System Mode, Int's disabled 00000004 0000006e 36 .long START1 ; 3rd and 4th: Jump to START1 (begin of monitor program) 00000008 37 PSA_extended_instr: ; Program Status for Extended Intruction Trap handler 00000008 0000 38 .word %0000 0000000a c000 39 .word %C000 0000000c 00000092 40 .long TRAP_extended_instr 00000010 41 PSA_privileged_instr: ; Program Status for Privileged instructions handler 00000010 0000 42 .word %0000 00000012 c000 43 .word %C000 00000014 00000094 44 .long TRAP_privileged_instr 00000018 45 PSA_SYSCALL: ; Program Status for SYSTEM CALL Trap handler 00000018 0000 46 .word %0000 0000001a c000 47 .word %C000 0000001c 00000096 48 .long SYSCALL 00000020 49 PSA_SEGT: ; Program Status for Segmentation Fault Trap Handler 00000020 0000 50 .word %0000 00000022 c000 51 .word %C000 00000024 000000b6 52 .long TRAP_SEGT 00000028 53 PSA_NMI: ; Program Status for NMI (Non-maskable Interrupt) Handler 00000028 0000 54 .word %0000 0000002a c000 55 .word %C000 0000002c 000000b8 56 .long TRAP_NMI 00000030 57 PSA_NVI: ; Program Status for NVI (Non-vectored Interrupt) Handler 00000030 0000 58 .word %0000 00000032 c000 59 .word %C000 00000034 000000ba 60 .long TRAP_NVI 00000038 61 PSA_VI_FCW: ; Reserved word and FCW for Vectored Interrupt handlers 00000038 0000 62 .word %0000 0000003a c000 63 .word %C000 0000003c 64 PSA_VI_0: ; Vectored interrupt handler addresses 0000003c 000000bc 65 .long TRAP_VI_0 00000040 66 PSA_VI_2: 00000040 000000be 67 .long TRAP_VI_2 00000044 68 PSA_VI_4: 00000044 000000c0 69 .long TRAP_VI_4 00000048 70 PSA_VI_6: 00000048 000000c2 71 .long TRAP_VI_6 0000004c 72 PSA_VI_8: 0000004c 000000c4 73 .long TRAP_VI_8 00000050 74 PSA_VI_10: 00000050 000000c6 75 .long TRAP_VI_10 00000054 76 PSA_VI_12: 00000054 000000c8 77 .long TRAP_VI_12 00000058 78 PSA_VI_14: 00000058 000000ca 79 .long TRAP_VI_14 0000005c 80 0000005c 81 0000005c 82 0000005c 83 ;=================================================================================== 0000005c 84 SCn_TABLE: 0000005c 85 0000005c 00000068 86 .long SC0_handler 00000060 0000006a 87 .long SC1_handler 00000064 0000006c 88 .long SC2_handler 00000068 89 00000068 90 ;---------------------------------------------------------------- 00000068 91 ;SCn_handler: Handler subroutines for SC, #n System Call instructions (separate subroutines for each #n) 00000068 92 ; See SYSCALL routine for explanation 00000068 93 SC0_handler: 00000068 9e08 94 RET 0000006a 95 SC1_handler: 0000006a 9e08 96 RET 0000006c 97 SC2_handler: 0000006c 9e08 98 RET 0000006e 99 ;*********************************************************************************** 0000006e 100 ;START1: Start of monitor program after power-up or RESET 0000006e 101 ; System Mode 0000006e 102 ; Segmented mode (to properly initialize stacks and PSA) 0000006e 103 .seg 0000006e 104 0000006e 105 START1: ; Firstly, initialize the stacks and the PSA 0000006e 106 0000006e 760e80000116 107 LDA RR14, Addr_System_Stack 00000074 760c80000116 108 LDA RR12, Addr_Normal_Stack 0000007a 760a80000000 109 LDA RR10, PSA_AREA 00000080 7dac 110 LDCTL PSAPSEG, R10 00000082 7dbd 111 LDCTL PSAPOFF, R11 00000084 7dce 112 LDCTL NSPSEG, R12 00000086 7ddf 113 LDCTL NSPOFF, R13 00000088 114 00000088 115 ; Change to nonsegmented mode for normal conditions (only traps/interrupts use segt code) 00000088 116 00000088 7dc2 117 LDCTL R12, FCW 0000008a a3cf 118 RES R12, #15 ; reset SEG bit 0000008c 7dca 119 LDCTL FCW, R12 0000008e 120 .nonseg 0000008e 121 0000008e 122 ; Now initialize the peripherals 0000008e 123 0000008e dfe2 124 CALR SUB_INIT_Peripherals 00000090 125 00000090 126 ; Finally, enable all interrupts: we're ready for action 00000090 127 00000090 7c04 128 EI vi, nvi 00000092 129 00000092 130 00000092 131 00000092 132 00000092 133 ;========================================================================== 00000092 134 ;TRAP_HANDLERS: Area for handling interrupts and software traps. 00000092 135 ;Important note: All trap handlers are executed in segmented mode 00000092 136 ; as IRET must be handled in segmented mode as well. 00000092 137 00000092 138 .seg 00000092 139 TRAP_HANDLERS: 00000092 140 00000092 141 TRAP_extended_instr: 00000092 7b00 142 IRET 00000094 143 TRAP_privileged_instr: 00000094 7b00 144 IRET 00000096 145 ;-------------------------------------------------------------------------- 00000096 146 ;SYSCALL: 00000096 147 ; System Call Trap handler, characteristics: 00000096 148 ; - Executes in segmented, system mode 00000096 149 ; - Is treated as a normal interrupt handling routine, i.e.: 00000096 150 ; - Executes with VI, NVI disabled (may be changed however by SCn_handler routines below) 00000096 151 ; - SYSCALL returns to calling program with IRET 00000096 152 ; - Calls a separate handling procedure SCn_handler for each identifier n in sc #n command 00000096 153 ; - SCn_handler must end with RET command, not IRET, in order to return to main SYSCALL handler 00000096 154 ; - SCn_handler is executed in segmented, system mode: 00000096 155 ; - must finally return to SYSCALL also in segmented, system mode, 00000096 156 ; - however may switch to nonsegmented mode before return. 00000096 157 ; - SCn_handler may change FCW flags of SC caller program 00000096 158 ; - Program Status is saved on stack, all SCn_handler routines deal with the following System Stack: 00000096 159 ; 00000096 160 ; SP-> #0 SYSCALL<> return address to SYSCALL (after RET is executed) 00000096 161 ; #2 SYSCALL<> return address to SYSCALL ( ,, ,, ,, ) 00000096 162 ; #4 - Saved R1 (pushed by SYSCALL for workspace) 00000096 163 ; #6 - Saved R2 (pushed by SYSCALL ,, ,, ) 00000096 164 ; #8 - Saved R3 (pushed by SYSCALL ,, ,, ) 00000096 165 ; #10 SC #n instruction (PROGRAM STATUS of SC invoker, used by IRET) 00000096 166 ; #12 FCW (PROGRAM STATUS of SC invoker, used by IRET) 00000096 167 ; #14 PC<> 00000096 168 ; #16 PC<> 00000096 169 ; #18 *** (Top of System Stack just before SC #n instruction was executed) 00000096 170 ; 00000096 171 ; - SCn_handler routines may take VIE, NVIE settings from caller's FCW (#12) to prevent unhandled interrupts 00000096 172 ; - SCn_handlers are called using address table SCn_TABLE containing segmented address entries 00000096 173 00000096 174 SYSCALL: 00000096 abf5 175 DEC R15, #6 ;Save workspace registers R1, RR2 00000098 1ce90102 176 LDM @RR14, R1, #3 ; ,, ,, ,, 0000009c 31e10006 177 LD R1,RR14(#6) ;Get SC #n instruction 000000a0 8c18 178 CLRB RH1 ;Prepare index for SCn_TABLE (containing subroutine call addrrs for each #n) 000000a2 b3110004 179 SLL R1, #4 ; - table contains longword addresses 000000a6 54128000005c 180 LDL RR2, SCn_TABLE(R1) ;Get #n-th entry (stored in Table SCn_TABLE) and load it in RR2 000000ac 1f20 181 CALL @RR2 ;Call of SCn_handler nr #n using handler address in RR2 000000ae 1ce10102 182 LDM R1, @RR14, #3 ;Workspace not needed anymore, restore registers 000000b2 a9f5 183 INC R15, #6 ; ,, ,, ,, ,, 000000b4 7b00 184 IRET 000000b6 185 TRAP_SEGT: 000000b6 7b00 186 IRET 000000b8 187 TRAP_NMI: 000000b8 7b00 188 IRET 000000ba 189 TRAP_NVI: 000000ba 7b00 190 IRET 000000bc 191 TRAP_VI_0: 000000bc 7b00 192 IRET 000000be 193 TRAP_VI_2: 000000be 7b00 194 IRET 000000c0 195 TRAP_VI_4: 000000c0 7b00 196 IRET 000000c2 197 TRAP_VI_6: 000000c2 7b00 198 IRET 000000c4 199 TRAP_VI_8: 000000c4 7b00 200 IRET 000000c6 201 TRAP_VI_10: 000000c6 7b00 202 IRET 000000c8 203 TRAP_VI_12: 000000c8 7b00 204 IRET 000000ca 205 TRAP_VI_14: 000000ca 7b00 206 IRET 000000cc 207 000000cc 208 000000cc 209 ;================================================== 000000cc 210 ;SUB_INIT_Peripherals: Subroutine to initialize peripherals 000000cc 211 SUB_INIT_Peripherals: 000000cc 9e08 212 RET 000000ce 213 000000ce 214 000000ce 215 ;************************************************** 000000ce 216 ;************************************************** 000000ce 217 ;* START of TINY BASIC * 000000ce 218 ;************************************************** 000000ce 219 ;************************************************** 000000ce 220 000000ce 221 .nonseg 000000ce 222 BASIC_START: 000000ce 5e0800de 223 JP START 000000d2 224 000000d2 225 CI11: 000000d2 7f01 226 SC #1 000000d4 9e08 227 RET 000000d6 228 CO11: 000000d6 7f02 229 SC #2 000000d8 9e08 230 RET 000000da 231 CSTS: 000000da 7f03 232 SC #3 000000dc 9e08 233 RET 000000de 234 000000de 235 START: 000000de 760f0116 236 LDA R15,Addr_Normal_Stack 000000e2 c9ff 237 LDB RL1,#%FF 000000e4 238 INIT: 000000e4 6e090114 239 LDB OCSW,RL1 000000e8 d000 240 CALR CRLF 000000ea 241 000000ea 242 000000ea 243 000000ea 244 CRLF: 000000ea c90d 245 LDB RL1,#%0D 000000ec 246 OUTC: 000000ec 93f6 247 PUSH @R15, R6 000000ee 93f1 248 PUSH @R15, R1 000000f0 60090114 249 LDB RL1, OCSW 000000f4 8499 250 ORB RL1, RL1 000000f6 251 OC2: 000000f6 ee03 252 JR NZ, OC3 000000f8 97f1 253 POP R1, @R15 000000fa 97f6 254 POP R6, @R15 000000fc 9e08 255 RET 000000fe 256 OC3: 000000fe 97f1 257 POP R1, @R15 00000100 93f1 258 PUSH @R15, R1 00000102 a09e 259 LDB RL6, RL1 00000104 260 LPT: 00000104 0a0e0d0d 261 CPB RL6, #%0D 00000108 e605 262 JR Z, LINEF 0000010a 263 H1: 0000010a a0e9 264 LDB RL1, RL6 0000010c d01c 265 CALR CO11 0000010e 97f1 266 POP R1, @R15 00000110 97f6 267 POP R6, @R15 00000112 9e08 268 RET 00000114 269 00000114 270 LINEF: 00000114 271 00000114 272 00000114 273 ;************************************************** 00000114 274 ;Storage memory 00000114 275 00000114 276 00000114 0001 277 OCSW: .word %0000 00000116 278 Addr_System_Stack: 00000116 279 Addr_Normal_Stack: 00000116 280 00000116 281 .end